/*
* FileSaver.js
* A saveAs() FileSaver implementation.
*
* By Eli Grey, http://eligrey.com
*
* License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
* source  : http://purl.eligrey.com/github/FileSaver.js
*/
// The one and only way of getting global scope in all environments
// https://stackoverflow.com/q/3277182/1008999
var _global = typeof window === 'object' && window.window === window
    ? window : typeof self === 'object' && self.self === self
        ? self : typeof global === 'object' && global.global === global
            ? global
            : this
function bom(blob, opts) {
    if (typeof opts === 'undefined') opts = { autoBom: false }
    else if (typeof opts !== 'object') {
        console.warn('Deprecated: Expected third argument to be a object')
        opts = { autoBom: !opts }
    }
    // prepend BOM for UTF-8 XML and text/* types (including HTML)
    // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
    if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
        return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type })
    }
    return blob
}
function download(url, name, opts) {
    var xhr = new XMLHttpRequest()
    xhr.open('GET', url)
    xhr.responseType = 'blob'
    xhr.onload = function () {
        saveAs(xhr.response, name, opts)
    }
    xhr.onerror = function () {
        console.error('could not download file')
    }
    xhr.send()
}
function corsEnabled(url) {
    var xhr = new XMLHttpRequest()
    // use sync to avoid popup blocker
    xhr.open('HEAD', url, false)
    try {
        xhr.send()
    } catch (e) { }
    return xhr.status >= 200 && xhr.status <= 299
}
// `a.click()` doesn't work for all browsers (#465)
function click(node) {
    try {
        node.dispatchEvent(new MouseEvent('click'))
    } catch (e) {
        var evt = document.createEvent('MouseEvents')
        evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80,
            20, false, false, false, false, 0, null)
        node.dispatchEvent(evt)
    }
}
// Detect WebView inside a native macOS app by ruling out all browsers
// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too
// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos
var isMacOSWebView = _global.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent)
var saveAs = _global.saveAs || (
    // probably in some web worker
    (typeof window !== 'object' || window !== _global)
        ? function saveAs() { /* noop */ }
        // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView
        : ('download' in HTMLAnchorElement.prototype && !isMacOSWebView)
            ? function saveAs(blob, name, opts) {
                var URL = _global.URL || _global.webkitURL
                var a = document.createElement('a')
                name = name || blob.name || 'download'
                a.download = name
                a.rel = 'noopener' // tabnabbing
                // TODO: detect chrome extensions & packaged apps
                // a.target = '_blank'
                if (typeof blob === 'string') {
                    // Support regular links
                    a.href = blob
                    if (a.origin !== location.origin) {
                        corsEnabled(a.href)
                            ? download(blob, name, opts)
                            : click(a, a.target = '_blank')
                    } else {
                        click(a)
                    }
                } else {
                    // Support blobs
                    a.href = URL.createObjectURL(blob)
                    setTimeout(function () { URL.revokeObjectURL(a.href) }, 4E4) // 40s
                    setTimeout(function () { click(a) }, 0)
                }
            }
            // Use msSaveOrOpenBlob as a second approach
            : 'msSaveOrOpenBlob' in navigator
                ? function saveAs(blob, name, opts) {
                    name = name || blob.name || 'download'
                    if (typeof blob === 'string') {
                        if (corsEnabled(blob)) {
                            download(blob, name, opts)
                        } else {
                            var a = document.createElement('a')
                            a.href = blob
                            a.target = '_blank'
                            setTimeout(function () { click(a) })
                        }
                    } else {
                        navigator.msSaveOrOpenBlob(bom(blob, opts), name)
                    }
                }
                // Fallback to using FileReader and a popup
                : function saveAs(blob, name, opts, popup) {
                    // Open a popup immediately do go around popup blocker
                    // Mostly only available on user interaction and the fileReader is async so...
                    popup = popup || open('', '_blank')
                    if (popup) {
                        popup.document.title =
                            popup.document.body.innerText = 'downloading...'
                    }
                    if (typeof blob === 'string') return download(blob, name, opts)
                    var force = blob.type === 'application/octet-stream'
                    var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari
                    var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent)
                    if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && typeof FileReader !== 'undefined') {
                        // Safari doesn't allow downloading of blob URLs
                        var reader = new FileReader()
                        reader.onloadend = function () {
                            var url = reader.result
                            url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;')
                            if (popup) popup.location.href = url
                            else location = url
                            popup = null // reverse-tabnabbing #460
                        }
                        reader.readAsDataURL(blob)
                    } else {
                        var URL = _global.URL || _global.webkitURL
                        var url = URL.createObjectURL(blob)
                        if (popup) popup.location = url
                        else location.href = url
                        popup = null // reverse-tabnabbing #460
                        setTimeout(function () { URL.revokeObjectURL(url) }, 4E4) // 40s
                    }
                }
)
_global.saveAs = saveAs.saveAs = saveAs
if (typeof module !== 'undefined') {
    module.exports = saveAs;
};
/*! ics.js Wed Sept 14 2017 */
var ics = function (e, t) { "use strict"; { if (!(navigator.userAgent.indexOf("MSIE") > -1 && -1 == navigator.userAgent.indexOf("MSIE 10"))) { void 0 === e && (e = "default"), void 0 === t && (t = "Calendar"); var r = -1 !== navigator.appVersion.indexOf("Win") ? "\r\n" : "\n", n = [], i = ["BEGIN:VCALENDAR", "PRODID:" + t, "VERSION:2.0"].join(r), o = r + "END:VCALENDAR", a = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"]; return { events: function () { return n }, calendar: function () { return i + r + n.join(r) + o }, addEvent: function (t, i, o, l, u, s) { if (void 0 === t || void 0 === i || void 0 === o || void 0 === l || void 0 === u) return !1; if (s && !s.rrule) { if ("YEARLY" !== s.freq && "MONTHLY" !== s.freq && "WEEKLY" !== s.freq && "DAILY" !== s.freq) throw "Recurrence rrule frequency must be provided and be one of the following: 'YEARLY', 'MONTHLY', 'WEEKLY', or 'DAILY'"; if (s.until && isNaN(Date.parse(s.until))) throw "Recurrence rrule 'until' must be a valid date string"; if (s.interval && isNaN(parseInt(s.interval))) throw "Recurrence rrule 'interval' must be an integer"; if (s.count && isNaN(parseInt(s.count))) throw "Recurrence rrule 'count' must be an integer"; if (void 0 !== s.byday) { if ("[object Array]" !== Object.prototype.toString.call(s.byday)) throw "Recurrence rrule 'byday' must be an array"; if (s.byday.length > 7) throw "Recurrence rrule 'byday' array must not be longer than the 7 days in a week"; s.byday = s.byday.filter(function (e, t) { return s.byday.indexOf(e) == t }); for (var c in s.byday) if (a.indexOf(s.byday[c]) < 0) throw "Recurrence rrule 'byday' values must include only the following: 'SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'" } } var g = new Date(l), d = new Date(u), f = new Date, S = ("0000" + g.getFullYear().toString()).slice(-4), E = ("00" + (g.getMonth() + 1).toString()).slice(-2), v = ("00" + g.getDate().toString()).slice(-2), y = ("00" + g.getHours().toString()).slice(-2), A = ("00" + g.getMinutes().toString()).slice(-2), T = ("00" + g.getSeconds().toString()).slice(-2), b = ("0000" + d.getFullYear().toString()).slice(-4), D = ("00" + (d.getMonth() + 1).toString()).slice(-2), N = ("00" + d.getDate().toString()).slice(-2), h = ("00" + d.getHours().toString()).slice(-2), I = ("00" + d.getMinutes().toString()).slice(-2), R = ("00" + d.getMinutes().toString()).slice(-2), M = ("0000" + f.getFullYear().toString()).slice(-4), w = ("00" + (f.getMonth() + 1).toString()).slice(-2), L = ("00" + f.getDate().toString()).slice(-2), O = ("00" + f.getHours().toString()).slice(-2), p = ("00" + f.getMinutes().toString()).slice(-2), Y = ("00" + f.getMinutes().toString()).slice(-2), U = "", V = ""; y + A + T + h + I + R != 0 && (U = "T" + y + A + T, V = "T" + h + I + R); var B, C = S + E + v + U, j = b + D + N + V, m = M + w + L + ("T" + O + p + Y); if (s) if (s.rrule) B = s.rrule; else { if (B = "rrule:FREQ=" + s.freq, s.until) { var x = new Date(Date.parse(s.until)).toISOString(); B += ";UNTIL=" + x.substring(0, x.length - 13).replace(/[-]/g, "") + "000000Z" } s.interval && (B += ";INTERVAL=" + s.interval), s.count && (B += ";COUNT=" + s.count), s.byday && s.byday.length > 0 && (B += ";BYDAY=" + s.byday.join(",")) } (new Date).toISOString(); var H = ["BEGIN:VEVENT", "UID:" + n.length + "@" + e, "CLASS:PUBLIC", "DESCRIPTION:" + i, "DTSTAMP;VALUE=DATE-TIME:" + m, "DTSTART;VALUE=DATE-TIME:" + C, "DTEND;VALUE=DATE-TIME:" + j, "LOCATION:" + o, "SUMMARY;LANGUAGE=en-us:" + t, "TRANSP:TRANSPARENT", "END:VEVENT"]; return B && H.splice(4, 0, B), H = H.join(r), n.push(H), H }, download: function (e, t) { if (n.length < 1) return !1; t = void 0 !== t ? t : ".ics", e = void 0 !== e ? e : "calendar"; var a, l = i + r + n.join(r) + o; if (-1 === navigator.userAgent.indexOf("MSIE 10")) a = new Blob([l]); else { var u = new BlobBuilder; u.append(l), a = u.getBlob("text/x-vCalendar;charset=" + document.characterSet) } return saveAs(a, e + t), l }, build: function () { return !(n.length < 1) && i + r + n.join(r) + o } } } console.log("Unsupported Browser") } };;
//! moment.js
//! version : 2.29.4
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com
;(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    global.moment = factory()
}(this, (function () { 'use strict';
    var hookCallback;
    function hooks() {
        return hookCallback.apply(null, arguments);
    }
    // This is done to register the method called with moment()
    // without creating circular dependencies.
    function setHookCallback(callback) {
        hookCallback = callback;
    }
    function isArray(input) {
        return (
            input instanceof Array ||
            Object.prototype.toString.call(input) === '[object Array]'
        );
    }
    function isObject(input) {
        // IE8 will treat undefined and null as object if it wasn't for
        // input != null
        return (
            input != null &&
            Object.prototype.toString.call(input) === '[object Object]'
        );
    }
    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }
    function isObjectEmpty(obj) {
        if (Object.getOwnPropertyNames) {
            return Object.getOwnPropertyNames(obj).length === 0;
        } else {
            var k;
            for (k in obj) {
                if (hasOwnProp(obj, k)) {
                    return false;
                }
            }
            return true;
        }
    }
    function isUndefined(input) {
        return input === void 0;
    }
    function isNumber(input) {
        return (
            typeof input === 'number' ||
            Object.prototype.toString.call(input) === '[object Number]'
        );
    }
    function isDate(input) {
        return (
            input instanceof Date ||
            Object.prototype.toString.call(input) === '[object Date]'
        );
    }
    function map(arr, fn) {
        var res = [],
            i,
            arrLen = arr.length;
        for (i = 0; i < arrLen; ++i) {
            res.push(fn(arr[i], i));
        }
        return res;
    }
    function extend(a, b) {
        for (var i in b) {
            if (hasOwnProp(b, i)) {
                a[i] = b[i];
            }
        }
        if (hasOwnProp(b, 'toString')) {
            a.toString = b.toString;
        }
        if (hasOwnProp(b, 'valueOf')) {
            a.valueOf = b.valueOf;
        }
        return a;
    }
    function createUTC(input, format, locale, strict) {
        return createLocalOrUTC(input, format, locale, strict, true).utc();
    }
    function defaultParsingFlags() {
        // We need to deep clone this object.
        return {
            empty: false,
            unusedTokens: [],
            unusedInput: [],
            overflow: -2,
            charsLeftOver: 0,
            nullInput: false,
            invalidEra: null,
            invalidMonth: null,
            invalidFormat: false,
            userInvalidated: false,
            iso: false,
            parsedDateParts: [],
            era: null,
            meridiem: null,
            rfc2822: false,
            weekdayMismatch: false,
        };
    }
    function getParsingFlags(m) {
        if (m._pf == null) {
            m._pf = defaultParsingFlags();
        }
        return m._pf;
    }
    var some;
    if (Array.prototype.some) {
        some = Array.prototype.some;
    } else {
        some = function (fun) {
            var t = Object(this),
                len = t.length >>> 0,
                i;
            for (i = 0; i < len; i++) {
                if (i in t && fun.call(this, t[i], i, t)) {
                    return true;
                }
            }
            return false;
        };
    }
    function isValid(m) {
        if (m._isValid == null) {
            var flags = getParsingFlags(m),
                parsedParts = some.call(flags.parsedDateParts, function (i) {
                    return i != null;
                }),
                isNowValid =
                    !isNaN(m._d.getTime()) &&
                    flags.overflow < 0 &&
                    !flags.empty &&
                    !flags.invalidEra &&
                    !flags.invalidMonth &&
                    !flags.invalidWeekday &&
                    !flags.weekdayMismatch &&
                    !flags.nullInput &&
                    !flags.invalidFormat &&
                    !flags.userInvalidated &&
                    (!flags.meridiem || (flags.meridiem && parsedParts));
            if (m._strict) {
                isNowValid =
                    isNowValid &&
                    flags.charsLeftOver === 0 &&
                    flags.unusedTokens.length === 0 &&
                    flags.bigHour === undefined;
            }
            if (Object.isFrozen == null || !Object.isFrozen(m)) {
                m._isValid = isNowValid;
            } else {
                return isNowValid;
            }
        }
        return m._isValid;
    }
    function createInvalid(flags) {
        var m = createUTC(NaN);
        if (flags != null) {
            extend(getParsingFlags(m), flags);
        } else {
            getParsingFlags(m).userInvalidated = true;
        }
        return m;
    }
    // Plugins that add properties should also add the key here (null value),
    // so we can properly clone ourselves.
    var momentProperties = (hooks.momentProperties = []),
        updateInProgress = false;
    function copyConfig(to, from) {
        var i,
            prop,
            val,
            momentPropertiesLen = momentProperties.length;
        if (!isUndefined(from._isAMomentObject)) {
            to._isAMomentObject = from._isAMomentObject;
        }
        if (!isUndefined(from._i)) {
            to._i = from._i;
        }
        if (!isUndefined(from._f)) {
            to._f = from._f;
        }
        if (!isUndefined(from._l)) {
            to._l = from._l;
        }
        if (!isUndefined(from._strict)) {
            to._strict = from._strict;
        }
        if (!isUndefined(from._tzm)) {
            to._tzm = from._tzm;
        }
        if (!isUndefined(from._isUTC)) {
            to._isUTC = from._isUTC;
        }
        if (!isUndefined(from._offset)) {
            to._offset = from._offset;
        }
        if (!isUndefined(from._pf)) {
            to._pf = getParsingFlags(from);
        }
        if (!isUndefined(from._locale)) {
            to._locale = from._locale;
        }
        if (momentPropertiesLen > 0) {
            for (i = 0; i < momentPropertiesLen; i++) {
                prop = momentProperties[i];
                val = from[prop];
                if (!isUndefined(val)) {
                    to[prop] = val;
                }
            }
        }
        return to;
    }
    // Moment prototype object
    function Moment(config) {
        copyConfig(this, config);
        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
        if (!this.isValid()) {
            this._d = new Date(NaN);
        }
        // Prevent infinite loop in case updateOffset creates new moment
        // objects.
        if (updateInProgress === false) {
            updateInProgress = true;
            hooks.updateOffset(this);
            updateInProgress = false;
        }
    }
    function isMoment(obj) {
        return (
            obj instanceof Moment || (obj != null && obj._isAMomentObject != null)
        );
    }
    function warn(msg) {
        if (
            hooks.suppressDeprecationWarnings === false &&
            typeof console !== 'undefined' &&
            console.warn
        ) {
            console.warn('Deprecation warning: ' + msg);
        }
    }
    function deprecate(msg, fn) {
        var firstTime = true;
        return extend(function () {
            if (hooks.deprecationHandler != null) {
                hooks.deprecationHandler(null, msg);
            }
            if (firstTime) {
                var args = [],
                    arg,
                    i,
                    key,
                    argLen = arguments.length;
                for (i = 0; i < argLen; i++) {
                    arg = '';
                    if (typeof arguments[i] === 'object') {
                        arg += '\n[' + i + '] ';
                        for (key in arguments[0]) {
                            if (hasOwnProp(arguments[0], key)) {
                                arg += key + ': ' + arguments[0][key] + ', ';
                            }
                        }
                        arg = arg.slice(0, -2); // Remove trailing comma and space
                    } else {
                        arg = arguments[i];
                    }
                    args.push(arg);
                }
                warn(
                    msg +
                        '\nArguments: ' +
                        Array.prototype.slice.call(args).join('') +
                        '\n' +
                        new Error().stack
                );
                firstTime = false;
            }
            return fn.apply(this, arguments);
        }, fn);
    }
    var deprecations = {};
    function deprecateSimple(name, msg) {
        if (hooks.deprecationHandler != null) {
            hooks.deprecationHandler(name, msg);
        }
        if (!deprecations[name]) {
            warn(msg);
            deprecations[name] = true;
        }
    }
    hooks.suppressDeprecationWarnings = false;
    hooks.deprecationHandler = null;
    function isFunction(input) {
        return (
            (typeof Function !== 'undefined' && input instanceof Function) ||
            Object.prototype.toString.call(input) === '[object Function]'
        );
    }
    function set(config) {
        var prop, i;
        for (i in config) {
            if (hasOwnProp(config, i)) {
                prop = config[i];
                if (isFunction(prop)) {
                    this[i] = prop;
                } else {
                    this['_' + i] = prop;
                }
            }
        }
        this._config = config;
        // Lenient ordinal parsing accepts just a number in addition to
        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
        // TODO: Remove "ordinalParse" fallback in next major release.
        this._dayOfMonthOrdinalParseLenient = new RegExp(
            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
                '|' +
                /\d{1,2}/.source
        );
    }
    function mergeConfigs(parentConfig, childConfig) {
        var res = extend({}, parentConfig),
            prop;
        for (prop in childConfig) {
            if (hasOwnProp(childConfig, prop)) {
                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
                    res[prop] = {};
                    extend(res[prop], parentConfig[prop]);
                    extend(res[prop], childConfig[prop]);
                } else if (childConfig[prop] != null) {
                    res[prop] = childConfig[prop];
                } else {
                    delete res[prop];
                }
            }
        }
        for (prop in parentConfig) {
            if (
                hasOwnProp(parentConfig, prop) &&
                !hasOwnProp(childConfig, prop) &&
                isObject(parentConfig[prop])
            ) {
                // make sure changes to properties don't modify parent config
                res[prop] = extend({}, res[prop]);
            }
        }
        return res;
    }
    function Locale(config) {
        if (config != null) {
            this.set(config);
        }
    }
    var keys;
    if (Object.keys) {
        keys = Object.keys;
    } else {
        keys = function (obj) {
            var i,
                res = [];
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        };
    }
    var defaultCalendar = {
        sameDay: '[Today at] LT',
        nextDay: '[Tomorrow at] LT',
        nextWeek: 'dddd [at] LT',
        lastDay: '[Yesterday at] LT',
        lastWeek: '[Last] dddd [at] LT',
        sameElse: 'L',
    };
    function calendar(key, mom, now) {
        var output = this._calendar[key] || this._calendar['sameElse'];
        return isFunction(output) ? output.call(mom, now) : output;
    }
    function zeroFill(number, targetLength, forceSign) {
        var absNumber = '' + Math.abs(number),
            zerosToFill = targetLength - absNumber.length,
            sign = number >= 0;
        return (
            (sign ? (forceSign ? '+' : '') : '-') +
            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) +
            absNumber
        );
    }
    var formattingTokens =
            /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,
        localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,
        formatFunctions = {},
        formatTokenFunctions = {};
    // token:    'M'
    // padded:   ['MM', 2]
    // ordinal:  'Mo'
    // callback: function () { this.month() + 1 }
    function addFormatToken(token, padded, ordinal, callback) {
        var func = callback;
        if (typeof callback === 'string') {
            func = function () {
                return this[callback]();
            };
        }
        if (token) {
            formatTokenFunctions[token] = func;
        }
        if (padded) {
            formatTokenFunctions[padded[0]] = function () {
                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
            };
        }
        if (ordinal) {
            formatTokenFunctions[ordinal] = function () {
                return this.localeData().ordinal(
                    func.apply(this, arguments),
                    token
                );
            };
        }
    }
    function removeFormattingTokens(input) {
        if (input.match(/\[[\s\S]/)) {
            return input.replace(/^\[|\]$/g, '');
        }
        return input.replace(/\\/g, '');
    }
    function makeFormatFunction(format) {
        var array = format.match(formattingTokens),
            i,
            length;
        for (i = 0, length = array.length; i < length; i++) {
            if (formatTokenFunctions[array[i]]) {
                array[i] = formatTokenFunctions[array[i]];
            } else {
                array[i] = removeFormattingTokens(array[i]);
            }
        }
        return function (mom) {
            var output = '',
                i;
            for (i = 0; i < length; i++) {
                output += isFunction(array[i])
                    ? array[i].call(mom, format)
                    : array[i];
            }
            return output;
        };
    }
    // format date using native date object
    function formatMoment(m, format) {
        if (!m.isValid()) {
            return m.localeData().invalidDate();
        }
        format = expandFormat(format, m.localeData());
        formatFunctions[format] =
            formatFunctions[format] || makeFormatFunction(format);
        return formatFunctions[format](m);
    }
    function expandFormat(format, locale) {
        var i = 5;
        function replaceLongDateFormatTokens(input) {
            return locale.longDateFormat(input) || input;
        }
        localFormattingTokens.lastIndex = 0;
        while (i >= 0 && localFormattingTokens.test(format)) {
            format = format.replace(
                localFormattingTokens,
                replaceLongDateFormatTokens
            );
            localFormattingTokens.lastIndex = 0;
            i -= 1;
        }
        return format;
    }
    var defaultLongDateFormat = {
        LTS: 'h:mm:ss A',
        LT: 'h:mm A',
        L: 'MM/DD/YYYY',
        LL: 'MMMM D, YYYY',
        LLL: 'MMMM D, YYYY h:mm A',
        LLLL: 'dddd, MMMM D, YYYY h:mm A',
    };
    function longDateFormat(key) {
        var format = this._longDateFormat[key],
            formatUpper = this._longDateFormat[key.toUpperCase()];
        if (format || !formatUpper) {
            return format;
        }
        this._longDateFormat[key] = formatUpper
            .match(formattingTokens)
            .map(function (tok) {
                if (
                    tok === 'MMMM' ||
                    tok === 'MM' ||
                    tok === 'DD' ||
                    tok === 'dddd'
                ) {
                    return tok.slice(1);
                }
                return tok;
            })
            .join('');
        return this._longDateFormat[key];
    }
    var defaultInvalidDate = 'Invalid date';
    function invalidDate() {
        return this._invalidDate;
    }
    var defaultOrdinal = '%d',
        defaultDayOfMonthOrdinalParse = /\d{1,2}/;
    function ordinal(number) {
        return this._ordinal.replace('%d', number);
    }
    var defaultRelativeTime = {
        future: 'in %s',
        past: '%s ago',
        s: 'a few seconds',
        ss: '%d seconds',
        m: 'a minute',
        mm: '%d minutes',
        h: 'an hour',
        hh: '%d hours',
        d: 'a day',
        dd: '%d days',
        w: 'a week',
        ww: '%d weeks',
        M: 'a month',
        MM: '%d months',
        y: 'a year',
        yy: '%d years',
    };
    function relativeTime(number, withoutSuffix, string, isFuture) {
        var output = this._relativeTime[string];
        return isFunction(output)
            ? output(number, withoutSuffix, string, isFuture)
            : output.replace(/%d/i, number);
    }
    function pastFuture(diff, output) {
        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
    }
    var aliases = {};
    function addUnitAlias(unit, shorthand) {
        var lowerCase = unit.toLowerCase();
        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
    }
    function normalizeUnits(units) {
        return typeof units === 'string'
            ? aliases[units] || aliases[units.toLowerCase()]
            : undefined;
    }
    function normalizeObjectUnits(inputObject) {
        var normalizedInput = {},
            normalizedProp,
            prop;
        for (prop in inputObject) {
            if (hasOwnProp(inputObject, prop)) {
                normalizedProp = normalizeUnits(prop);
                if (normalizedProp) {
                    normalizedInput[normalizedProp] = inputObject[prop];
                }
            }
        }
        return normalizedInput;
    }
    var priorities = {};
    function addUnitPriority(unit, priority) {
        priorities[unit] = priority;
    }
    function getPrioritizedUnits(unitsObj) {
        var units = [],
            u;
        for (u in unitsObj) {
            if (hasOwnProp(unitsObj, u)) {
                units.push({ unit: u, priority: priorities[u] });
            }
        }
        units.sort(function (a, b) {
            return a.priority - b.priority;
        });
        return units;
    }
    function isLeapYear(year) {
        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
    }
    function absFloor(number) {
        if (number < 0) {
            // -0 -> 0
            return Math.ceil(number) || 0;
        } else {
            return Math.floor(number);
        }
    }
    function toInt(argumentForCoercion) {
        var coercedNumber = +argumentForCoercion,
            value = 0;
        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
            value = absFloor(coercedNumber);
        }
        return value;
    }
    function makeGetSet(unit, keepTime) {
        return function (value) {
            if (value != null) {
                set$1(this, unit, value);
                hooks.updateOffset(this, keepTime);
                return this;
            } else {
                return get(this, unit);
            }
        };
    }
    function get(mom, unit) {
        return mom.isValid()
            ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]()
            : NaN;
    }
    function set$1(mom, unit, value) {
        if (mom.isValid() && !isNaN(value)) {
            if (
                unit === 'FullYear' &&
                isLeapYear(mom.year()) &&
                mom.month() === 1 &&
                mom.date() === 29
            ) {
                value = toInt(value);
                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](
                    value,
                    mom.month(),
                    daysInMonth(value, mom.month())
                );
            } else {
                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
            }
        }
    }
    // MOMENTS
    function stringGet(units) {
        units = normalizeUnits(units);
        if (isFunction(this[units])) {
            return this[units]();
        }
        return this;
    }
    function stringSet(units, value) {
        if (typeof units === 'object') {
            units = normalizeObjectUnits(units);
            var prioritized = getPrioritizedUnits(units),
                i,
                prioritizedLen = prioritized.length;
            for (i = 0; i < prioritizedLen; i++) {
                this[prioritized[i].unit](units[prioritized[i].unit]);
            }
        } else {
            units = normalizeUnits(units);
            if (isFunction(this[units])) {
                return this[units](value);
            }
        }
        return this;
    }
    var match1 = /\d/, //       0 - 9
        match2 = /\d\d/, //      00 - 99
        match3 = /\d{3}/, //     000 - 999
        match4 = /\d{4}/, //    0000 - 9999
        match6 = /[+-]?\d{6}/, // -999999 - 999999
        match1to2 = /\d\d?/, //       0 - 99
        match3to4 = /\d\d\d\d?/, //     999 - 9999
        match5to6 = /\d\d\d\d\d\d?/, //   99999 - 999999
        match1to3 = /\d{1,3}/, //       0 - 999
        match1to4 = /\d{1,4}/, //       0 - 9999
        match1to6 = /[+-]?\d{1,6}/, // -999999 - 999999
        matchUnsigned = /\d+/, //       0 - inf
        matchSigned = /[+-]?\d+/, //    -inf - inf
        matchOffset = /Z|[+-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
        matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, // +00 -00 +00:00 -00:00 +0000 -0000 or Z
        matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
        // any word (or two) characters or numbers including two/three word month in arabic.
        // includes scottish gaelic two word and hyphenated months
        matchWord =
            /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,
        regexes;
    regexes = {};
    function addRegexToken(token, regex, strictRegex) {
        regexes[token] = isFunction(regex)
            ? regex
            : function (isStrict, localeData) {
                  return isStrict && strictRegex ? strictRegex : regex;
              };
    }
    function getParseRegexForToken(token, config) {
        if (!hasOwnProp(regexes, token)) {
            return new RegExp(unescapeFormat(token));
        }
        return regexes[token](config._strict, config._locale);
    }
    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
    function unescapeFormat(s) {
        return regexEscape(
            s
                .replace('\\', '')
                .replace(
                    /\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,
                    function (matched, p1, p2, p3, p4) {
                        return p1 || p2 || p3 || p4;
                    }
                )
        );
    }
    function regexEscape(s) {
        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    }
    var tokens = {};
    function addParseToken(token, callback) {
        var i,
            func = callback,
            tokenLen;
        if (typeof token === 'string') {
            token = [token];
        }
        if (isNumber(callback)) {
            func = function (input, array) {
                array[callback] = toInt(input);
            };
        }
        tokenLen = token.length;
        for (i = 0; i < tokenLen; i++) {
            tokens[token[i]] = func;
        }
    }
    function addWeekParseToken(token, callback) {
        addParseToken(token, function (input, array, config, token) {
            config._w = config._w || {};
            callback(input, config._w, config, token);
        });
    }
    function addTimeToArrayFromToken(token, input, config) {
        if (input != null && hasOwnProp(tokens, token)) {
            tokens[token](input, config._a, config, token);
        }
    }
    var YEAR = 0,
        MONTH = 1,
        DATE = 2,
        HOUR = 3,
        MINUTE = 4,
        SECOND = 5,
        MILLISECOND = 6,
        WEEK = 7,
        WEEKDAY = 8;
    function mod(n, x) {
        return ((n % x) + x) % x;
    }
    var indexOf;
    if (Array.prototype.indexOf) {
        indexOf = Array.prototype.indexOf;
    } else {
        indexOf = function (o) {
            // I know
            var i;
            for (i = 0; i < this.length; ++i) {
                if (this[i] === o) {
                    return i;
                }
            }
            return -1;
        };
    }
    function daysInMonth(year, month) {
        if (isNaN(year) || isNaN(month)) {
            return NaN;
        }
        var modMonth = mod(month, 12);
        year += (month - modMonth) / 12;
        return modMonth === 1
            ? isLeapYear(year)
                ? 29
                : 28
            : 31 - ((modMonth % 7) % 2);
    }
    // FORMATTING
    addFormatToken('M', ['MM', 2], 'Mo', function () {
        return this.month() + 1;
    });
    addFormatToken('MMM', 0, 0, function (format) {
        return this.localeData().monthsShort(this, format);
    });
    addFormatToken('MMMM', 0, 0, function (format) {
        return this.localeData().months(this, format);
    });
    // ALIASES
    addUnitAlias('month', 'M');
    // PRIORITY
    addUnitPriority('month', 8);
    // PARSING
    addRegexToken('M', match1to2);
    addRegexToken('MM', match1to2, match2);
    addRegexToken('MMM', function (isStrict, locale) {
        return locale.monthsShortRegex(isStrict);
    });
    addRegexToken('MMMM', function (isStrict, locale) {
        return locale.monthsRegex(isStrict);
    });
    addParseToken(['M', 'MM'], function (input, array) {
        array[MONTH] = toInt(input) - 1;
    });
    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
        var month = config._locale.monthsParse(input, token, config._strict);
        // if we didn't find a month name, mark the date as invalid.
        if (month != null) {
            array[MONTH] = month;
        } else {
            getParsingFlags(config).invalidMonth = input;
        }
    });
    // LOCALES
    var defaultLocaleMonths =
            'January_February_March_April_May_June_July_August_September_October_November_December'.split(
                '_'
            ),
        defaultLocaleMonthsShort =
            'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
        MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,
        defaultMonthsShortRegex = matchWord,
        defaultMonthsRegex = matchWord;
    function localeMonths(m, format) {
        if (!m) {
            return isArray(this._months)
                ? this._months
                : this._months['standalone'];
        }
        return isArray(this._months)
            ? this._months[m.month()]
            : this._months[
                  (this._months.isFormat || MONTHS_IN_FORMAT).test(format)
                      ? 'format'
                      : 'standalone'
              ][m.month()];
    }
    function localeMonthsShort(m, format) {
        if (!m) {
            return isArray(this._monthsShort)
                ? this._monthsShort
                : this._monthsShort['standalone'];
        }
        return isArray(this._monthsShort)
            ? this._monthsShort[m.month()]
            : this._monthsShort[
                  MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'
              ][m.month()];
    }
    function handleStrictParse(monthName, format, strict) {
        var i,
            ii,
            mom,
            llc = monthName.toLocaleLowerCase();
        if (!this._monthsParse) {
            // this is not used
            this._monthsParse = [];
            this._longMonthsParse = [];
            this._shortMonthsParse = [];
            for (i = 0; i < 12; ++i) {
                mom = createUTC([2000, i]);
                this._shortMonthsParse[i] = this.monthsShort(
                    mom,
                    ''
                ).toLocaleLowerCase();
                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
            }
        }
        if (strict) {
            if (format === 'MMM') {
                ii = indexOf.call(this._shortMonthsParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._longMonthsParse, llc);
                return ii !== -1 ? ii : null;
            }
        } else {
            if (format === 'MMM') {
                ii = indexOf.call(this._shortMonthsParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._longMonthsParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._longMonthsParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortMonthsParse, llc);
                return ii !== -1 ? ii : null;
            }
        }
    }
    function localeMonthsParse(monthName, format, strict) {
        var i, mom, regex;
        if (this._monthsParseExact) {
            return handleStrictParse.call(this, monthName, format, strict);
        }
        if (!this._monthsParse) {
            this._monthsParse = [];
            this._longMonthsParse = [];
            this._shortMonthsParse = [];
        }
        // TODO: add sorting
        // Sorting makes sure if one month (or abbr) is a prefix of another
        // see sorting in computeMonthsParse
        for (i = 0; i < 12; i++) {
            // make the regex if we don't have it already
            mom = createUTC([2000, i]);
            if (strict && !this._longMonthsParse[i]) {
                this._longMonthsParse[i] = new RegExp(
                    '^' + this.months(mom, '').replace('.', '') + '$',
                    'i'
                );
                this._shortMonthsParse[i] = new RegExp(
                    '^' + this.monthsShort(mom, '').replace('.', '') + '$',
                    'i'
                );
            }
            if (!strict && !this._monthsParse[i]) {
                regex =
                    '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
            }
            // test the regex
            if (
                strict &&
                format === 'MMMM' &&
                this._longMonthsParse[i].test(monthName)
            ) {
                return i;
            } else if (
                strict &&
                format === 'MMM' &&
                this._shortMonthsParse[i].test(monthName)
            ) {
                return i;
            } else if (!strict && this._monthsParse[i].test(monthName)) {
                return i;
            }
        }
    }
    // MOMENTS
    function setMonth(mom, value) {
        var dayOfMonth;
        if (!mom.isValid()) {
            // No op
            return mom;
        }
        if (typeof value === 'string') {
            if (/^\d+$/.test(value)) {
                value = toInt(value);
            } else {
                value = mom.localeData().monthsParse(value);
                // TODO: Another silent failure?
                if (!isNumber(value)) {
                    return mom;
                }
            }
        }
        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
        return mom;
    }
    function getSetMonth(value) {
        if (value != null) {
            setMonth(this, value);
            hooks.updateOffset(this, true);
            return this;
        } else {
            return get(this, 'Month');
        }
    }
    function getDaysInMonth() {
        return daysInMonth(this.year(), this.month());
    }
    function monthsShortRegex(isStrict) {
        if (this._monthsParseExact) {
            if (!hasOwnProp(this, '_monthsRegex')) {
                computeMonthsParse.call(this);
            }
            if (isStrict) {
                return this._monthsShortStrictRegex;
            } else {
                return this._monthsShortRegex;
            }
        } else {
            if (!hasOwnProp(this, '_monthsShortRegex')) {
                this._monthsShortRegex = defaultMonthsShortRegex;
            }
            return this._monthsShortStrictRegex && isStrict
                ? this._monthsShortStrictRegex
                : this._monthsShortRegex;
        }
    }
    function monthsRegex(isStrict) {
        if (this._monthsParseExact) {
            if (!hasOwnProp(this, '_monthsRegex')) {
                computeMonthsParse.call(this);
            }
            if (isStrict) {
                return this._monthsStrictRegex;
            } else {
                return this._monthsRegex;
            }
        } else {
            if (!hasOwnProp(this, '_monthsRegex')) {
                this._monthsRegex = defaultMonthsRegex;
            }
            return this._monthsStrictRegex && isStrict
                ? this._monthsStrictRegex
                : this._monthsRegex;
        }
    }
    function computeMonthsParse() {
        function cmpLenRev(a, b) {
            return b.length - a.length;
        }
        var shortPieces = [],
            longPieces = [],
            mixedPieces = [],
            i,
            mom;
        for (i = 0; i < 12; i++) {
            // make the regex if we don't have it already
            mom = createUTC([2000, i]);
            shortPieces.push(this.monthsShort(mom, ''));
            longPieces.push(this.months(mom, ''));
            mixedPieces.push(this.months(mom, ''));
            mixedPieces.push(this.monthsShort(mom, ''));
        }
        // Sorting makes sure if one month (or abbr) is a prefix of another it
        // will match the longer piece.
        shortPieces.sort(cmpLenRev);
        longPieces.sort(cmpLenRev);
        mixedPieces.sort(cmpLenRev);
        for (i = 0; i < 12; i++) {
            shortPieces[i] = regexEscape(shortPieces[i]);
            longPieces[i] = regexEscape(longPieces[i]);
        }
        for (i = 0; i < 24; i++) {
            mixedPieces[i] = regexEscape(mixedPieces[i]);
        }
        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
        this._monthsShortRegex = this._monthsRegex;
        this._monthsStrictRegex = new RegExp(
            '^(' + longPieces.join('|') + ')',
            'i'
        );
        this._monthsShortStrictRegex = new RegExp(
            '^(' + shortPieces.join('|') + ')',
            'i'
        );
    }
    // FORMATTING
    addFormatToken('Y', 0, 0, function () {
        var y = this.year();
        return y <= 9999 ? zeroFill(y, 4) : '+' + y;
    });
    addFormatToken(0, ['YY', 2], 0, function () {
        return this.year() % 100;
    });
    addFormatToken(0, ['YYYY', 4], 0, 'year');
    addFormatToken(0, ['YYYYY', 5], 0, 'year');
    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
    // ALIASES
    addUnitAlias('year', 'y');
    // PRIORITIES
    addUnitPriority('year', 1);
    // PARSING
    addRegexToken('Y', matchSigned);
    addRegexToken('YY', match1to2, match2);
    addRegexToken('YYYY', match1to4, match4);
    addRegexToken('YYYYY', match1to6, match6);
    addRegexToken('YYYYYY', match1to6, match6);
    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
    addParseToken('YYYY', function (input, array) {
        array[YEAR] =
            input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
    });
    addParseToken('YY', function (input, array) {
        array[YEAR] = hooks.parseTwoDigitYear(input);
    });
    addParseToken('Y', function (input, array) {
        array[YEAR] = parseInt(input, 10);
    });
    // HELPERS
    function daysInYear(year) {
        return isLeapYear(year) ? 366 : 365;
    }
    // HOOKS
    hooks.parseTwoDigitYear = function (input) {
        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
    };
    // MOMENTS
    var getSetYear = makeGetSet('FullYear', true);
    function getIsLeapYear() {
        return isLeapYear(this.year());
    }
    function createDate(y, m, d, h, M, s, ms) {
        // can't just apply() to create a date:
        // https://stackoverflow.com/q/181348
        var date;
        // the date constructor remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0) {
            // preserve leap years using a full 400 year cycle, then reset
            date = new Date(y + 400, m, d, h, M, s, ms);
            if (isFinite(date.getFullYear())) {
                date.setFullYear(y);
            }
        } else {
            date = new Date(y, m, d, h, M, s, ms);
        }
        return date;
    }
    function createUTCDate(y) {
        var date, args;
        // the Date.UTC function remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0) {
            args = Array.prototype.slice.call(arguments);
            // preserve leap years using a full 400 year cycle, then reset
            args[0] = y + 400;
            date = new Date(Date.UTC.apply(null, args));
            if (isFinite(date.getUTCFullYear())) {
                date.setUTCFullYear(y);
            }
        } else {
            date = new Date(Date.UTC.apply(null, arguments));
        }
        return date;
    }
    // start-of-first-week - start-of-year
    function firstWeekOffset(year, dow, doy) {
        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
            fwd = 7 + dow - doy,
            // first-week day local weekday -- which local weekday is fwd
            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
        return -fwdlw + fwd - 1;
    }
    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
        var localWeekday = (7 + weekday - dow) % 7,
            weekOffset = firstWeekOffset(year, dow, doy),
            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
            resYear,
            resDayOfYear;
        if (dayOfYear <= 0) {
            resYear = year - 1;
            resDayOfYear = daysInYear(resYear) + dayOfYear;
        } else if (dayOfYear > daysInYear(year)) {
            resYear = year + 1;
            resDayOfYear = dayOfYear - daysInYear(year);
        } else {
            resYear = year;
            resDayOfYear = dayOfYear;
        }
        return {
            year: resYear,
            dayOfYear: resDayOfYear,
        };
    }
    function weekOfYear(mom, dow, doy) {
        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
            resWeek,
            resYear;
        if (week < 1) {
            resYear = mom.year() - 1;
            resWeek = week + weeksInYear(resYear, dow, doy);
        } else if (week > weeksInYear(mom.year(), dow, doy)) {
            resWeek = week - weeksInYear(mom.year(), dow, doy);
            resYear = mom.year() + 1;
        } else {
            resYear = mom.year();
            resWeek = week;
        }
        return {
            week: resWeek,
            year: resYear,
        };
    }
    function weeksInYear(year, dow, doy) {
        var weekOffset = firstWeekOffset(year, dow, doy),
            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
    }
    // FORMATTING
    addFormatToken('w', ['ww', 2], 'wo', 'week');
    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
    // ALIASES
    addUnitAlias('week', 'w');
    addUnitAlias('isoWeek', 'W');
    // PRIORITIES
    addUnitPriority('week', 5);
    addUnitPriority('isoWeek', 5);
    // PARSING
    addRegexToken('w', match1to2);
    addRegexToken('ww', match1to2, match2);
    addRegexToken('W', match1to2);
    addRegexToken('WW', match1to2, match2);
    addWeekParseToken(
        ['w', 'ww', 'W', 'WW'],
        function (input, week, config, token) {
            week[token.substr(0, 1)] = toInt(input);
        }
    );
    // HELPERS
    // LOCALES
    function localeWeek(mom) {
        return weekOfYear(mom, this._week.dow, this._week.doy).week;
    }
    var defaultLocaleWeek = {
        dow: 0, // Sunday is the first day of the week.
        doy: 6, // The week that contains Jan 6th is the first week of the year.
    };
    function localeFirstDayOfWeek() {
        return this._week.dow;
    }
    function localeFirstDayOfYear() {
        return this._week.doy;
    }
    // MOMENTS
    function getSetWeek(input) {
        var week = this.localeData().week(this);
        return input == null ? week : this.add((input - week) * 7, 'd');
    }
    function getSetISOWeek(input) {
        var week = weekOfYear(this, 1, 4).week;
        return input == null ? week : this.add((input - week) * 7, 'd');
    }
    // FORMATTING
    addFormatToken('d', 0, 'do', 'day');
    addFormatToken('dd', 0, 0, function (format) {
        return this.localeData().weekdaysMin(this, format);
    });
    addFormatToken('ddd', 0, 0, function (format) {
        return this.localeData().weekdaysShort(this, format);
    });
    addFormatToken('dddd', 0, 0, function (format) {
        return this.localeData().weekdays(this, format);
    });
    addFormatToken('e', 0, 0, 'weekday');
    addFormatToken('E', 0, 0, 'isoWeekday');
    // ALIASES
    addUnitAlias('day', 'd');
    addUnitAlias('weekday', 'e');
    addUnitAlias('isoWeekday', 'E');
    // PRIORITY
    addUnitPriority('day', 11);
    addUnitPriority('weekday', 11);
    addUnitPriority('isoWeekday', 11);
    // PARSING
    addRegexToken('d', match1to2);
    addRegexToken('e', match1to2);
    addRegexToken('E', match1to2);
    addRegexToken('dd', function (isStrict, locale) {
        return locale.weekdaysMinRegex(isStrict);
    });
    addRegexToken('ddd', function (isStrict, locale) {
        return locale.weekdaysShortRegex(isStrict);
    });
    addRegexToken('dddd', function (isStrict, locale) {
        return locale.weekdaysRegex(isStrict);
    });
    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
        var weekday = config._locale.weekdaysParse(input, token, config._strict);
        // if we didn't get a weekday name, mark the date as invalid
        if (weekday != null) {
            week.d = weekday;
        } else {
            getParsingFlags(config).invalidWeekday = input;
        }
    });
    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
        week[token] = toInt(input);
    });
    // HELPERS
    function parseWeekday(input, locale) {
        if (typeof input !== 'string') {
            return input;
        }
        if (!isNaN(input)) {
            return parseInt(input, 10);
        }
        input = locale.weekdaysParse(input);
        if (typeof input === 'number') {
            return input;
        }
        return null;
    }
    function parseIsoWeekday(input, locale) {
        if (typeof input === 'string') {
            return locale.weekdaysParse(input) % 7 || 7;
        }
        return isNaN(input) ? null : input;
    }
    // LOCALES
    function shiftWeekdays(ws, n) {
        return ws.slice(n, 7).concat(ws.slice(0, n));
    }
    var defaultLocaleWeekdays =
            'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
        defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
        defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
        defaultWeekdaysRegex = matchWord,
        defaultWeekdaysShortRegex = matchWord,
        defaultWeekdaysMinRegex = matchWord;
    function localeWeekdays(m, format) {
        var weekdays = isArray(this._weekdays)
            ? this._weekdays
            : this._weekdays[
                  m && m !== true && this._weekdays.isFormat.test(format)
                      ? 'format'
                      : 'standalone'
              ];
        return m === true
            ? shiftWeekdays(weekdays, this._week.dow)
            : m
            ? weekdays[m.day()]
            : weekdays;
    }
    function localeWeekdaysShort(m) {
        return m === true
            ? shiftWeekdays(this._weekdaysShort, this._week.dow)
            : m
            ? this._weekdaysShort[m.day()]
            : this._weekdaysShort;
    }
    function localeWeekdaysMin(m) {
        return m === true
            ? shiftWeekdays(this._weekdaysMin, this._week.dow)
            : m
            ? this._weekdaysMin[m.day()]
            : this._weekdaysMin;
    }
    function handleStrictParse$1(weekdayName, format, strict) {
        var i,
            ii,
            mom,
            llc = weekdayName.toLocaleLowerCase();
        if (!this._weekdaysParse) {
            this._weekdaysParse = [];
            this._shortWeekdaysParse = [];
            this._minWeekdaysParse = [];
            for (i = 0; i < 7; ++i) {
                mom = createUTC([2000, 1]).day(i);
                this._minWeekdaysParse[i] = this.weekdaysMin(
                    mom,
                    ''
                ).toLocaleLowerCase();
                this._shortWeekdaysParse[i] = this.weekdaysShort(
                    mom,
                    ''
                ).toLocaleLowerCase();
                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
            }
        }
        if (strict) {
            if (format === 'dddd') {
                ii = indexOf.call(this._weekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else if (format === 'ddd') {
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            }
        } else {
            if (format === 'dddd') {
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else if (format === 'ddd') {
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._minWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            }
        }
    }
    function localeWeekdaysParse(weekdayName, format, strict) {
        var i, mom, regex;
        if (this._weekdaysParseExact) {
            return handleStrictParse$1.call(this, weekdayName, format, strict);
        }
        if (!this._weekdaysParse) {
            this._weekdaysParse = [];
            this._minWeekdaysParse = [];
            this._shortWeekdaysParse = [];
            this._fullWeekdaysParse = [];
        }
        for (i = 0; i < 7; i++) {
            // make the regex if we don't have it already
            mom = createUTC([2000, 1]).day(i);
            if (strict && !this._fullWeekdaysParse[i]) {
                this._fullWeekdaysParse[i] = new RegExp(
                    '^' + this.weekdays(mom, '').replace('.', '\\.?') + '$',
                    'i'
                );
                this._shortWeekdaysParse[i] = new RegExp(
                    '^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$',
                    'i'
                );
                this._minWeekdaysParse[i] = new RegExp(
                    '^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$',
                    'i'
                );
            }
            if (!this._weekdaysParse[i]) {
                regex =
                    '^' +
                    this.weekdays(mom, '') +
                    '|^' +
                    this.weekdaysShort(mom, '') +
                    '|^' +
                    this.weekdaysMin(mom, '');
                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
            }
            // test the regex
            if (
                strict &&
                format === 'dddd' &&
                this._fullWeekdaysParse[i].test(weekdayName)
            ) {
                return i;
            } else if (
                strict &&
                format === 'ddd' &&
                this._shortWeekdaysParse[i].test(weekdayName)
            ) {
                return i;
            } else if (
                strict &&
                format === 'dd' &&
                this._minWeekdaysParse[i].test(weekdayName)
            ) {
                return i;
            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
                return i;
            }
        }
    }
    // MOMENTS
    function getSetDayOfWeek(input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
        if (input != null) {
            input = parseWeekday(input, this.localeData());
            return this.add(input - day, 'd');
        } else {
            return day;
        }
    }
    function getSetLocaleDayOfWeek(input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
        return input == null ? weekday : this.add(input - weekday, 'd');
    }
    function getSetISODayOfWeek(input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        // behaves the same as moment#day except
        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
        // as a setter, sunday should belong to the previous week.
        if (input != null) {
            var weekday = parseIsoWeekday(input, this.localeData());
            return this.day(this.day() % 7 ? weekday : weekday - 7);
        } else {
            return this.day() || 7;
        }
    }
    function weekdaysRegex(isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysStrictRegex;
            } else {
                return this._weekdaysRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                this._weekdaysRegex = defaultWeekdaysRegex;
            }
            return this._weekdaysStrictRegex && isStrict
                ? this._weekdaysStrictRegex
                : this._weekdaysRegex;
        }
    }
    function weekdaysShortRegex(isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysShortStrictRegex;
            } else {
                return this._weekdaysShortRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
            }
            return this._weekdaysShortStrictRegex && isStrict
                ? this._weekdaysShortStrictRegex
                : this._weekdaysShortRegex;
        }
    }
    function weekdaysMinRegex(isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysMinStrictRegex;
            } else {
                return this._weekdaysMinRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
            }
            return this._weekdaysMinStrictRegex && isStrict
                ? this._weekdaysMinStrictRegex
                : this._weekdaysMinRegex;
        }
    }
    function computeWeekdaysParse() {
        function cmpLenRev(a, b) {
            return b.length - a.length;
        }
        var minPieces = [],
            shortPieces = [],
            longPieces = [],
            mixedPieces = [],
            i,
            mom,
            minp,
            shortp,
            longp;
        for (i = 0; i < 7; i++) {
            // make the regex if we don't have it already
            mom = createUTC([2000, 1]).day(i);
            minp = regexEscape(this.weekdaysMin(mom, ''));
            shortp = regexEscape(this.weekdaysShort(mom, ''));
            longp = regexEscape(this.weekdays(mom, ''));
            minPieces.push(minp);
            shortPieces.push(shortp);
            longPieces.push(longp);
            mixedPieces.push(minp);
            mixedPieces.push(shortp);
            mixedPieces.push(longp);
        }
        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
        // will match the longer piece.
        minPieces.sort(cmpLenRev);
        shortPieces.sort(cmpLenRev);
        longPieces.sort(cmpLenRev);
        mixedPieces.sort(cmpLenRev);
        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
        this._weekdaysShortRegex = this._weekdaysRegex;
        this._weekdaysMinRegex = this._weekdaysRegex;
        this._weekdaysStrictRegex = new RegExp(
            '^(' + longPieces.join('|') + ')',
            'i'
        );
        this._weekdaysShortStrictRegex = new RegExp(
            '^(' + shortPieces.join('|') + ')',
            'i'
        );
        this._weekdaysMinStrictRegex = new RegExp(
            '^(' + minPieces.join('|') + ')',
            'i'
        );
    }
    // FORMATTING
    function hFormat() {
        return this.hours() % 12 || 12;
    }
    function kFormat() {
        return this.hours() || 24;
    }
    addFormatToken('H', ['HH', 2], 0, 'hour');
    addFormatToken('h', ['hh', 2], 0, hFormat);
    addFormatToken('k', ['kk', 2], 0, kFormat);
    addFormatToken('hmm', 0, 0, function () {
        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
    });
    addFormatToken('hmmss', 0, 0, function () {
        return (
            '' +
            hFormat.apply(this) +
            zeroFill(this.minutes(), 2) +
            zeroFill(this.seconds(), 2)
        );
    });
    addFormatToken('Hmm', 0, 0, function () {
        return '' + this.hours() + zeroFill(this.minutes(), 2);
    });
    addFormatToken('Hmmss', 0, 0, function () {
        return (
            '' +
            this.hours() +
            zeroFill(this.minutes(), 2) +
            zeroFill(this.seconds(), 2)
        );
    });
    function meridiem(token, lowercase) {
        addFormatToken(token, 0, 0, function () {
            return this.localeData().meridiem(
                this.hours(),
                this.minutes(),
                lowercase
            );
        });
    }
    meridiem('a', true);
    meridiem('A', false);
    // ALIASES
    addUnitAlias('hour', 'h');
    // PRIORITY
    addUnitPriority('hour', 13);
    // PARSING
    function matchMeridiem(isStrict, locale) {
        return locale._meridiemParse;
    }
    addRegexToken('a', matchMeridiem);
    addRegexToken('A', matchMeridiem);
    addRegexToken('H', match1to2);
    addRegexToken('h', match1to2);
    addRegexToken('k', match1to2);
    addRegexToken('HH', match1to2, match2);
    addRegexToken('hh', match1to2, match2);
    addRegexToken('kk', match1to2, match2);
    addRegexToken('hmm', match3to4);
    addRegexToken('hmmss', match5to6);
    addRegexToken('Hmm', match3to4);
    addRegexToken('Hmmss', match5to6);
    addParseToken(['H', 'HH'], HOUR);
    addParseToken(['k', 'kk'], function (input, array, config) {
        var kInput = toInt(input);
        array[HOUR] = kInput === 24 ? 0 : kInput;
    });
    addParseToken(['a', 'A'], function (input, array, config) {
        config._isPm = config._locale.isPM(input);
        config._meridiem = input;
    });
    addParseToken(['h', 'hh'], function (input, array, config) {
        array[HOUR] = toInt(input);
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('hmm', function (input, array, config) {
        var pos = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos));
        array[MINUTE] = toInt(input.substr(pos));
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('hmmss', function (input, array, config) {
        var pos1 = input.length - 4,
            pos2 = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos1));
        array[MINUTE] = toInt(input.substr(pos1, 2));
        array[SECOND] = toInt(input.substr(pos2));
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('Hmm', function (input, array, config) {
        var pos = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos));
        array[MINUTE] = toInt(input.substr(pos));
    });
    addParseToken('Hmmss', function (input, array, config) {
        var pos1 = input.length - 4,
            pos2 = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos1));
        array[MINUTE] = toInt(input.substr(pos1, 2));
        array[SECOND] = toInt(input.substr(pos2));
    });
    // LOCALES
    function localeIsPM(input) {
        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
        // Using charAt should be more compatible.
        return (input + '').toLowerCase().charAt(0) === 'p';
    }
    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i,
        // Setting the hour should keep the time, because the user explicitly
        // specified which hour they want. So trying to maintain the same hour (in
        // a new timezone) makes sense. Adding/subtracting hours does not follow
        // this rule.
        getSetHour = makeGetSet('Hours', true);
    function localeMeridiem(hours, minutes, isLower) {
        if (hours > 11) {
            return isLower ? 'pm' : 'PM';
        } else {
            return isLower ? 'am' : 'AM';
        }
    }
    var baseConfig = {
        calendar: defaultCalendar,
        longDateFormat: defaultLongDateFormat,
        invalidDate: defaultInvalidDate,
        ordinal: defaultOrdinal,
        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
        relativeTime: defaultRelativeTime,
        months: defaultLocaleMonths,
        monthsShort: defaultLocaleMonthsShort,
        week: defaultLocaleWeek,
        weekdays: defaultLocaleWeekdays,
        weekdaysMin: defaultLocaleWeekdaysMin,
        weekdaysShort: defaultLocaleWeekdaysShort,
        meridiemParse: defaultLocaleMeridiemParse,
    };
    // internal storage for locale config files
    var locales = {},
        localeFamilies = {},
        globalLocale;
    function commonPrefix(arr1, arr2) {
        var i,
            minl = Math.min(arr1.length, arr2.length);
        for (i = 0; i < minl; i += 1) {
            if (arr1[i] !== arr2[i]) {
                return i;
            }
        }
        return minl;
    }
    function normalizeLocale(key) {
        return key ? key.toLowerCase().replace('_', '-') : key;
    }
    // pick the locale from the array
    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
    function chooseLocale(names) {
        var i = 0,
            j,
            next,
            locale,
            split;
        while (i < names.length) {
            split = normalizeLocale(names[i]).split('-');
            j = split.length;
            next = normalizeLocale(names[i + 1]);
            next = next ? next.split('-') : null;
            while (j > 0) {
                locale = loadLocale(split.slice(0, j).join('-'));
                if (locale) {
                    return locale;
                }
                if (
                    next &&
                    next.length >= j &&
                    commonPrefix(split, next) >= j - 1
                ) {
                    //the next array item is better than a shallower substring of this one
                    break;
                }
                j--;
            }
            i++;
        }
        return globalLocale;
    }
    function isLocaleNameSane(name) {
        // Prevent names that look like filesystem paths, i.e contain '/' or '\'
        return name.match('^[^/\\\\]*$') != null;
    }
    function loadLocale(name) {
        var oldLocale = null,
            aliasedRequire;
        // TODO: Find a better way to register and load all the locales in Node
        if (
            locales[name] === undefined &&
            typeof module !== 'undefined' &&
            module &&
            module.exports &&
            isLocaleNameSane(name)
        ) {
            try {
                oldLocale = globalLocale._abbr;
                aliasedRequire = require;
                aliasedRequire('./locale/' + name);
                getSetGlobalLocale(oldLocale);
            } catch (e) {
                // mark as not found to avoid repeating expensive file require call causing high CPU
                // when trying to find en-US, en_US, en-us for every format call
                locales[name] = null; // null means not found
            }
        }
        return locales[name];
    }
    // This function will load locale and then set the global locale.  If
    // no arguments are passed in, it will simply return the current global
    // locale key.
    function getSetGlobalLocale(key, values) {
        var data;
        if (key) {
            if (isUndefined(values)) {
                data = getLocale(key);
            } else {
                data = defineLocale(key, values);
            }
            if (data) {
                // moment.duration._locale = moment._locale = data;
                globalLocale = data;
            } else {
                if (typeof console !== 'undefined' && console.warn) {
                    //warn user if arguments are passed but the locale could not be set
                    console.warn(
                        'Locale ' + key + ' not found. Did you forget to load it?'
                    );
                }
            }
        }
        return globalLocale._abbr;
    }
    function defineLocale(name, config) {
        if (config !== null) {
            var locale,
                parentConfig = baseConfig;
            config.abbr = name;
            if (locales[name] != null) {
                deprecateSimple(
                    'defineLocaleOverride',
                    'use moment.updateLocale(localeName, config) to change ' +
                        'an existing locale. moment.defineLocale(localeName, ' +
                        'config) should only be used for creating a new locale ' +
                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'
                );
                parentConfig = locales[name]._config;
            } else if (config.parentLocale != null) {
                if (locales[config.parentLocale] != null) {
                    parentConfig = locales[config.parentLocale]._config;
                } else {
                    locale = loadLocale(config.parentLocale);
                    if (locale != null) {
                        parentConfig = locale._config;
                    } else {
                        if (!localeFamilies[config.parentLocale]) {
                            localeFamilies[config.parentLocale] = [];
                        }
                        localeFamilies[config.parentLocale].push({
                            name: name,
                            config: config,
                        });
                        return null;
                    }
                }
            }
            locales[name] = new Locale(mergeConfigs(parentConfig, config));
            if (localeFamilies[name]) {
                localeFamilies[name].forEach(function (x) {
                    defineLocale(x.name, x.config);
                });
            }
            // backwards compat for now: also set the locale
            // make sure we set the locale AFTER all child locales have been
            // created, so we won't end up with the child locale set.
            getSetGlobalLocale(name);
            return locales[name];
        } else {
            // useful for testing
            delete locales[name];
            return null;
        }
    }
    function updateLocale(name, config) {
        if (config != null) {
            var locale,
                tmpLocale,
                parentConfig = baseConfig;
            if (locales[name] != null && locales[name].parentLocale != null) {
                // Update existing child locale in-place to avoid memory-leaks
                locales[name].set(mergeConfigs(locales[name]._config, config));
            } else {
                // MERGE
                tmpLocale = loadLocale(name);
                if (tmpLocale != null) {
                    parentConfig = tmpLocale._config;
                }
                config = mergeConfigs(parentConfig, config);
                if (tmpLocale == null) {
                    // updateLocale is called for creating a new locale
                    // Set abbr so it will have a name (getters return
                    // undefined otherwise).
                    config.abbr = name;
                }
                locale = new Locale(config);
                locale.parentLocale = locales[name];
                locales[name] = locale;
            }
            // backwards compat for now: also set the locale
            getSetGlobalLocale(name);
        } else {
            // pass null for config to unupdate, useful for tests
            if (locales[name] != null) {
                if (locales[name].parentLocale != null) {
                    locales[name] = locales[name].parentLocale;
                    if (name === getSetGlobalLocale()) {
                        getSetGlobalLocale(name);
                    }
                } else if (locales[name] != null) {
                    delete locales[name];
                }
            }
        }
        return locales[name];
    }
    // returns locale data
    function getLocale(key) {
        var locale;
        if (key && key._locale && key._locale._abbr) {
            key = key._locale._abbr;
        }
        if (!key) {
            return globalLocale;
        }
        if (!isArray(key)) {
            //short-circuit everything else
            locale = loadLocale(key);
            if (locale) {
                return locale;
            }
            key = [key];
        }
        return chooseLocale(key);
    }
    function listLocales() {
        return keys(locales);
    }
    function checkOverflow(m) {
        var overflow,
            a = m._a;
        if (a && getParsingFlags(m).overflow === -2) {
            overflow =
                a[MONTH] < 0 || a[MONTH] > 11
                    ? MONTH
                    : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH])
                    ? DATE
                    : a[HOUR] < 0 ||
                      a[HOUR] > 24 ||
                      (a[HOUR] === 24 &&
                          (a[MINUTE] !== 0 ||
                              a[SECOND] !== 0 ||
                              a[MILLISECOND] !== 0))
                    ? HOUR
                    : a[MINUTE] < 0 || a[MINUTE] > 59
                    ? MINUTE
                    : a[SECOND] < 0 || a[SECOND] > 59
                    ? SECOND
                    : a[MILLISECOND] < 0 || a[MILLISECOND] > 999
                    ? MILLISECOND
                    : -1;
            if (
                getParsingFlags(m)._overflowDayOfYear &&
                (overflow < YEAR || overflow > DATE)
            ) {
                overflow = DATE;
            }
            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
                overflow = WEEK;
            }
            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
                overflow = WEEKDAY;
            }
            getParsingFlags(m).overflow = overflow;
        }
        return m;
    }
    // iso 8601 regex
    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
    var extendedIsoRegex =
            /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
        basicIsoRegex =
            /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
        tzRegex = /Z|[+-]\d\d(?::?\d\d)?/,
        isoDates = [
            ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
            ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
            ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
            ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
            ['YYYY-DDD', /\d{4}-\d{3}/],
            ['YYYY-MM', /\d{4}-\d\d/, false],
            ['YYYYYYMMDD', /[+-]\d{10}/],
            ['YYYYMMDD', /\d{8}/],
            ['GGGG[W]WWE', /\d{4}W\d{3}/],
            ['GGGG[W]WW', /\d{4}W\d{2}/, false],
            ['YYYYDDD', /\d{7}/],
            ['YYYYMM', /\d{6}/, false],
            ['YYYY', /\d{4}/, false],
        ],
        // iso time formats and regexes
        isoTimes = [
            ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
            ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
            ['HH:mm:ss', /\d\d:\d\d:\d\d/],
            ['HH:mm', /\d\d:\d\d/],
            ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
            ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
            ['HHmmss', /\d\d\d\d\d\d/],
            ['HHmm', /\d\d\d\d/],
            ['HH', /\d\d/],
        ],
        aspNetJsonRegex = /^\/?Date\((-?\d+)/i,
        // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
        rfc2822 =
            /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,
        obsOffsets = {
            UT: 0,
            GMT: 0,
            EDT: -4 * 60,
            EST: -5 * 60,
            CDT: -5 * 60,
            CST: -6 * 60,
            MDT: -6 * 60,
            MST: -7 * 60,
            PDT: -7 * 60,
            PST: -8 * 60,
        };
    // date from iso format
    function configFromISO(config) {
        var i,
            l,
            string = config._i,
            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
            allowTime,
            dateFormat,
            timeFormat,
            tzFormat,
            isoDatesLen = isoDates.length,
            isoTimesLen = isoTimes.length;
        if (match) {
            getParsingFlags(config).iso = true;
            for (i = 0, l = isoDatesLen; i < l; i++) {
                if (isoDates[i][1].exec(match[1])) {
                    dateFormat = isoDates[i][0];
                    allowTime = isoDates[i][2] !== false;
                    break;
                }
            }
            if (dateFormat == null) {
                config._isValid = false;
                return;
            }
            if (match[3]) {
                for (i = 0, l = isoTimesLen; i < l; i++) {
                    if (isoTimes[i][1].exec(match[3])) {
                        // match[2] should be 'T' or space
                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
                        break;
                    }
                }
                if (timeFormat == null) {
                    config._isValid = false;
                    return;
                }
            }
            if (!allowTime && timeFormat != null) {
                config._isValid = false;
                return;
            }
            if (match[4]) {
                if (tzRegex.exec(match[4])) {
                    tzFormat = 'Z';
                } else {
                    config._isValid = false;
                    return;
                }
            }
            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
            configFromStringAndFormat(config);
        } else {
            config._isValid = false;
        }
    }
    function extractFromRFC2822Strings(
        yearStr,
        monthStr,
        dayStr,
        hourStr,
        minuteStr,
        secondStr
    ) {
        var result = [
            untruncateYear(yearStr),
            defaultLocaleMonthsShort.indexOf(monthStr),
            parseInt(dayStr, 10),
            parseInt(hourStr, 10),
            parseInt(minuteStr, 10),
        ];
        if (secondStr) {
            result.push(parseInt(secondStr, 10));
        }
        return result;
    }
    function untruncateYear(yearStr) {
        var year = parseInt(yearStr, 10);
        if (year <= 49) {
            return 2000 + year;
        } else if (year <= 999) {
            return 1900 + year;
        }
        return year;
    }
    function preprocessRFC2822(s) {
        // Remove comments and folding whitespace and replace multiple-spaces with a single space
        return s
            .replace(/\([^()]*\)|[\n\t]/g, ' ')
            .replace(/(\s\s+)/g, ' ')
            .replace(/^\s\s*/, '')
            .replace(/\s\s*$/, '');
    }
    function checkWeekday(weekdayStr, parsedInput, config) {
        if (weekdayStr) {
            // TODO: Replace the vanilla JS Date object with an independent day-of-week check.
            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
                weekdayActual = new Date(
                    parsedInput[0],
                    parsedInput[1],
                    parsedInput[2]
                ).getDay();
            if (weekdayProvided !== weekdayActual) {
                getParsingFlags(config).weekdayMismatch = true;
                config._isValid = false;
                return false;
            }
        }
        return true;
    }
    function calculateOffset(obsOffset, militaryOffset, numOffset) {
        if (obsOffset) {
            return obsOffsets[obsOffset];
        } else if (militaryOffset) {
            // the only allowed military tz is Z
            return 0;
        } else {
            var hm = parseInt(numOffset, 10),
                m = hm % 100,
                h = (hm - m) / 100;
            return h * 60 + m;
        }
    }
    // date and time from ref 2822 format
    function configFromRFC2822(config) {
        var match = rfc2822.exec(preprocessRFC2822(config._i)),
            parsedArray;
        if (match) {
            parsedArray = extractFromRFC2822Strings(
                match[4],
                match[3],
                match[2],
                match[5],
                match[6],
                match[7]
            );
            if (!checkWeekday(match[1], parsedArray, config)) {
                return;
            }
            config._a = parsedArray;
            config._tzm = calculateOffset(match[8], match[9], match[10]);
            config._d = createUTCDate.apply(null, config._a);
            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
            getParsingFlags(config).rfc2822 = true;
        } else {
            config._isValid = false;
        }
    }
    // date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict
    function configFromString(config) {
        var matched = aspNetJsonRegex.exec(config._i);
        if (matched !== null) {
            config._d = new Date(+matched[1]);
            return;
        }
        configFromISO(config);
        if (config._isValid === false) {
            delete config._isValid;
        } else {
            return;
        }
        configFromRFC2822(config);
        if (config._isValid === false) {
            delete config._isValid;
        } else {
            return;
        }
        if (config._strict) {
            config._isValid = false;
        } else {
            // Final attempt, use Input Fallback
            hooks.createFromInputFallback(config);
        }
    }
    hooks.createFromInputFallback = deprecate(
        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
            'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
            'discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.',
        function (config) {
            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
        }
    );
    // Pick the first defined of two or three arguments.
    function defaults(a, b, c) {
        if (a != null) {
            return a;
        }
        if (b != null) {
            return b;
        }
        return c;
    }
    function currentDateArray(config) {
        // hooks is actually the exported moment object
        var nowValue = new Date(hooks.now());
        if (config._useUTC) {
            return [
                nowValue.getUTCFullYear(),
                nowValue.getUTCMonth(),
                nowValue.getUTCDate(),
            ];
        }
        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
    }
    // convert an array to a date.
    // the array should mirror the parameters below
    // note: all values past the year are optional and will default to the lowest possible value.
    // [year, month, day , hour, minute, second, millisecond]
    function configFromArray(config) {
        var i,
            date,
            input = [],
            currentDate,
            expectedWeekday,
            yearToUse;
        if (config._d) {
            return;
        }
        currentDate = currentDateArray(config);
        //compute day of the year from weeks and weekdays
        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
            dayOfYearFromWeekInfo(config);
        }
        //if the day of the year is set, figure out what it is
        if (config._dayOfYear != null) {
            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
            if (
                config._dayOfYear > daysInYear(yearToUse) ||
                config._dayOfYear === 0
            ) {
                getParsingFlags(config)._overflowDayOfYear = true;
            }
            date = createUTCDate(yearToUse, 0, config._dayOfYear);
            config._a[MONTH] = date.getUTCMonth();
            config._a[DATE] = date.getUTCDate();
        }
        // Default to current date.
        // * if no year, month, day of month are given, default to today
        // * if day of month is given, default month and year
        // * if month is given, default only year
        // * if year is given, don't default anything
        for (i = 0; i < 3 && config._a[i] == null; ++i) {
            config._a[i] = input[i] = currentDate[i];
        }
        // Zero out whatever was not defaulted, including time
        for (; i < 7; i++) {
            config._a[i] = input[i] =
                config._a[i] == null ? (i === 2 ? 1 : 0) : config._a[i];
        }
        // Check for 24:00:00.000
        if (
            config._a[HOUR] === 24 &&
            config._a[MINUTE] === 0 &&
            config._a[SECOND] === 0 &&
            config._a[MILLISECOND] === 0
        ) {
            config._nextDay = true;
            config._a[HOUR] = 0;
        }
        config._d = (config._useUTC ? createUTCDate : createDate).apply(
            null,
            input
        );
        expectedWeekday = config._useUTC
            ? config._d.getUTCDay()
            : config._d.getDay();
        // Apply timezone offset from input. The actual utcOffset can be changed
        // with parseZone.
        if (config._tzm != null) {
            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
        }
        if (config._nextDay) {
            config._a[HOUR] = 24;
        }
        // check for mismatching day of week
        if (
            config._w &&
            typeof config._w.d !== 'undefined' &&
            config._w.d !== expectedWeekday
        ) {
            getParsingFlags(config).weekdayMismatch = true;
        }
    }
    function dayOfYearFromWeekInfo(config) {
        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek;
        w = config._w;
        if (w.GG != null || w.W != null || w.E != null) {
            dow = 1;
            doy = 4;
            // TODO: We need to take the current isoWeekYear, but that depends on
            // how we interpret now (local, utc, fixed offset). So create
            // a now version of current config (take local/utc/offset flags, and
            // create now).
            weekYear = defaults(
                w.GG,
                config._a[YEAR],
                weekOfYear(createLocal(), 1, 4).year
            );
            week = defaults(w.W, 1);
            weekday = defaults(w.E, 1);
            if (weekday < 1 || weekday > 7) {
                weekdayOverflow = true;
            }
        } else {
            dow = config._locale._week.dow;
            doy = config._locale._week.doy;
            curWeek = weekOfYear(createLocal(), dow, doy);
            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
            // Default to current week.
            week = defaults(w.w, curWeek.week);
            if (w.d != null) {
                // weekday -- low day numbers are considered next week
                weekday = w.d;
                if (weekday < 0 || weekday > 6) {
                    weekdayOverflow = true;
                }
            } else if (w.e != null) {
                // local weekday -- counting starts from beginning of week
                weekday = w.e + dow;
                if (w.e < 0 || w.e > 6) {
                    weekdayOverflow = true;
                }
            } else {
                // default to beginning of week
                weekday = dow;
            }
        }
        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
            getParsingFlags(config)._overflowWeeks = true;
        } else if (weekdayOverflow != null) {
            getParsingFlags(config)._overflowWeekday = true;
        } else {
            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
            config._a[YEAR] = temp.year;
            config._dayOfYear = temp.dayOfYear;
        }
    }
    // constant that refers to the ISO standard
    hooks.ISO_8601 = function () {};
    // constant that refers to the RFC 2822 form
    hooks.RFC_2822 = function () {};
    // date from string and format string
    function configFromStringAndFormat(config) {
        // TODO: Move this to another part of the creation flow to prevent circular deps
        if (config._f === hooks.ISO_8601) {
            configFromISO(config);
            return;
        }
        if (config._f === hooks.RFC_2822) {
            configFromRFC2822(config);
            return;
        }
        config._a = [];
        getParsingFlags(config).empty = true;
        // This array is used to make a Date, either with `new Date` or `Date.UTC`
        var string = '' + config._i,
            i,
            parsedInput,
            tokens,
            token,
            skipped,
            stringLength = string.length,
            totalParsedInputLength = 0,
            era,
            tokenLen;
        tokens =
            expandFormat(config._f, config._locale).match(formattingTokens) || [];
        tokenLen = tokens.length;
        for (i = 0; i < tokenLen; i++) {
            token = tokens[i];
            parsedInput = (string.match(getParseRegexForToken(token, config)) ||
                [])[0];
            if (parsedInput) {
                skipped = string.substr(0, string.indexOf(parsedInput));
                if (skipped.length > 0) {
                    getParsingFlags(config).unusedInput.push(skipped);
                }
                string = string.slice(
                    string.indexOf(parsedInput) + parsedInput.length
                );
                totalParsedInputLength += parsedInput.length;
            }
            // don't parse if it's not a known token
            if (formatTokenFunctions[token]) {
                if (parsedInput) {
                    getParsingFlags(config).empty = false;
                } else {
                    getParsingFlags(config).unusedTokens.push(token);
                }
                addTimeToArrayFromToken(token, parsedInput, config);
            } else if (config._strict && !parsedInput) {
                getParsingFlags(config).unusedTokens.push(token);
            }
        }
        // add remaining unparsed input length to the string
        getParsingFlags(config).charsLeftOver =
            stringLength - totalParsedInputLength;
        if (string.length > 0) {
            getParsingFlags(config).unusedInput.push(string);
        }
        // clear _12h flag if hour is <= 12
        if (
            config._a[HOUR] <= 12 &&
            getParsingFlags(config).bigHour === true &&
            config._a[HOUR] > 0
        ) {
            getParsingFlags(config).bigHour = undefined;
        }
        getParsingFlags(config).parsedDateParts = config._a.slice(0);
        getParsingFlags(config).meridiem = config._meridiem;
        // handle meridiem
        config._a[HOUR] = meridiemFixWrap(
            config._locale,
            config._a[HOUR],
            config._meridiem
        );
        // handle era
        era = getParsingFlags(config).era;
        if (era !== null) {
            config._a[YEAR] = config._locale.erasConvertYear(era, config._a[YEAR]);
        }
        configFromArray(config);
        checkOverflow(config);
    }
    function meridiemFixWrap(locale, hour, meridiem) {
        var isPm;
        if (meridiem == null) {
            // nothing to do
            return hour;
        }
        if (locale.meridiemHour != null) {
            return locale.meridiemHour(hour, meridiem);
        } else if (locale.isPM != null) {
            // Fallback
            isPm = locale.isPM(meridiem);
            if (isPm && hour < 12) {
                hour += 12;
            }
            if (!isPm && hour === 12) {
                hour = 0;
            }
            return hour;
        } else {
            // this is not supposed to happen
            return hour;
        }
    }
    // date from string and array of format strings
    function configFromStringAndArray(config) {
        var tempConfig,
            bestMoment,
            scoreToBeat,
            i,
            currentScore,
            validFormatFound,
            bestFormatIsValid = false,
            configfLen = config._f.length;
        if (configfLen === 0) {
            getParsingFlags(config).invalidFormat = true;
            config._d = new Date(NaN);
            return;
        }
        for (i = 0; i < configfLen; i++) {
            currentScore = 0;
            validFormatFound = false;
            tempConfig = copyConfig({}, config);
            if (config._useUTC != null) {
                tempConfig._useUTC = config._useUTC;
            }
            tempConfig._f = config._f[i];
            configFromStringAndFormat(tempConfig);
            if (isValid(tempConfig)) {
                validFormatFound = true;
            }
            // if there is any input that was not parsed add a penalty for that format
            currentScore += getParsingFlags(tempConfig).charsLeftOver;
            //or tokens
            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
            getParsingFlags(tempConfig).score = currentScore;
            if (!bestFormatIsValid) {
                if (
                    scoreToBeat == null ||
                    currentScore < scoreToBeat ||
                    validFormatFound
                ) {
                    scoreToBeat = currentScore;
                    bestMoment = tempConfig;
                    if (validFormatFound) {
                        bestFormatIsValid = true;
                    }
                }
            } else {
                if (currentScore < scoreToBeat) {
                    scoreToBeat = currentScore;
                    bestMoment = tempConfig;
                }
            }
        }
        extend(config, bestMoment || tempConfig);
    }
    function configFromObject(config) {
        if (config._d) {
            return;
        }
        var i = normalizeObjectUnits(config._i),
            dayOrDate = i.day === undefined ? i.date : i.day;
        config._a = map(
            [i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond],
            function (obj) {
                return obj && parseInt(obj, 10);
            }
        );
        configFromArray(config);
    }
    function createFromConfig(config) {
        var res = new Moment(checkOverflow(prepareConfig(config)));
        if (res._nextDay) {
            // Adding is smart enough around DST
            res.add(1, 'd');
            res._nextDay = undefined;
        }
        return res;
    }
    function prepareConfig(config) {
        var input = config._i,
            format = config._f;
        config._locale = config._locale || getLocale(config._l);
        if (input === null || (format === undefined && input === '')) {
            return createInvalid({ nullInput: true });
        }
        if (typeof input === 'string') {
            config._i = input = config._locale.preparse(input);
        }
        if (isMoment(input)) {
            return new Moment(checkOverflow(input));
        } else if (isDate(input)) {
            config._d = input;
        } else if (isArray(format)) {
            configFromStringAndArray(config);
        } else if (format) {
            configFromStringAndFormat(config);
        } else {
            configFromInput(config);
        }
        if (!isValid(config)) {
            config._d = null;
        }
        return config;
    }
    function configFromInput(config) {
        var input = config._i;
        if (isUndefined(input)) {
            config._d = new Date(hooks.now());
        } else if (isDate(input)) {
            config._d = new Date(input.valueOf());
        } else if (typeof input === 'string') {
            configFromString(config);
        } else if (isArray(input)) {
            config._a = map(input.slice(0), function (obj) {
                return parseInt(obj, 10);
            });
            configFromArray(config);
        } else if (isObject(input)) {
            configFromObject(config);
        } else if (isNumber(input)) {
            // from milliseconds
            config._d = new Date(input);
        } else {
            hooks.createFromInputFallback(config);
        }
    }
    function createLocalOrUTC(input, format, locale, strict, isUTC) {
        var c = {};
        if (format === true || format === false) {
            strict = format;
            format = undefined;
        }
        if (locale === true || locale === false) {
            strict = locale;
            locale = undefined;
        }
        if (
            (isObject(input) && isObjectEmpty(input)) ||
            (isArray(input) && input.length === 0)
        ) {
            input = undefined;
        }
        // object construction must be done this way.
        // https://github.com/moment/moment/issues/1423
        c._isAMomentObject = true;
        c._useUTC = c._isUTC = isUTC;
        c._l = locale;
        c._i = input;
        c._f = format;
        c._strict = strict;
        return createFromConfig(c);
    }
    function createLocal(input, format, locale, strict) {
        return createLocalOrUTC(input, format, locale, strict, false);
    }
    var prototypeMin = deprecate(
            'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
            function () {
                var other = createLocal.apply(null, arguments);
                if (this.isValid() && other.isValid()) {
                    return other < this ? this : other;
                } else {
                    return createInvalid();
                }
            }
        ),
        prototypeMax = deprecate(
            'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
            function () {
                var other = createLocal.apply(null, arguments);
                if (this.isValid() && other.isValid()) {
                    return other > this ? this : other;
                } else {
                    return createInvalid();
                }
            }
        );
    // Pick a moment m from moments so that m[fn](other) is true for all
    // other. This relies on the function fn to be transitive.
    // moments should either be an array of moment objects or an array, whose
    // first element is an array of moment objects.
    function pickBy(fn, moments) {
        var res, i;
        if (moments.length === 1 && isArray(moments[0])) {
            moments = moments[0];
        }
        if (!moments.length) {
            return createLocal();
        }
        res = moments[0];
        for (i = 1; i < moments.length; ++i) {
            if (!moments[i].isValid() || moments[i][fn](res)) {
                res = moments[i];
            }
        }
        return res;
    }
    // TODO: Use [].sort instead?
    function min() {
        var args = [].slice.call(arguments, 0);
        return pickBy('isBefore', args);
    }
    function max() {
        var args = [].slice.call(arguments, 0);
        return pickBy('isAfter', args);
    }
    var now = function () {
        return Date.now ? Date.now() : +new Date();
    };
    var ordering = [
        'year',
        'quarter',
        'month',
        'week',
        'day',
        'hour',
        'minute',
        'second',
        'millisecond',
    ];
    function isDurationValid(m) {
        var key,
            unitHasDecimal = false,
            i,
            orderLen = ordering.length;
        for (key in m) {
            if (
                hasOwnProp(m, key) &&
                !(
                    indexOf.call(ordering, key) !== -1 &&
                    (m[key] == null || !isNaN(m[key]))
                )
            ) {
                return false;
            }
        }
        for (i = 0; i < orderLen; ++i) {
            if (m[ordering[i]]) {
                if (unitHasDecimal) {
                    return false; // only allow non-integers for smallest unit
                }
                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
                    unitHasDecimal = true;
                }
            }
        }
        return true;
    }
    function isValid$1() {
        return this._isValid;
    }
    function createInvalid$1() {
        return createDuration(NaN);
    }
    function Duration(duration) {
        var normalizedInput = normalizeObjectUnits(duration),
            years = normalizedInput.year || 0,
            quarters = normalizedInput.quarter || 0,
            months = normalizedInput.month || 0,
            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
            days = normalizedInput.day || 0,
            hours = normalizedInput.hour || 0,
            minutes = normalizedInput.minute || 0,
            seconds = normalizedInput.second || 0,
            milliseconds = normalizedInput.millisecond || 0;
        this._isValid = isDurationValid(normalizedInput);
        // representation for dateAddRemove
        this._milliseconds =
            +milliseconds +
            seconds * 1e3 + // 1000
            minutes * 6e4 + // 1000 * 60
            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
        // Because of dateAddRemove treats 24 hours as different from a
        // day when working around DST, we need to store them separately
        this._days = +days + weeks * 7;
        // It is impossible to translate months into days without knowing
        // which months you are are talking about, so we have to store
        // it separately.
        this._months = +months + quarters * 3 + years * 12;
        this._data = {};
        this._locale = getLocale();
        this._bubble();
    }
    function isDuration(obj) {
        return obj instanceof Duration;
    }
    function absRound(number) {
        if (number < 0) {
            return Math.round(-1 * number) * -1;
        } else {
            return Math.round(number);
        }
    }
    // compare two arrays, return the number of differences
    function compareArrays(array1, array2, dontConvert) {
        var len = Math.min(array1.length, array2.length),
            lengthDiff = Math.abs(array1.length - array2.length),
            diffs = 0,
            i;
        for (i = 0; i < len; i++) {
            if (
                (dontConvert && array1[i] !== array2[i]) ||
                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))
            ) {
                diffs++;
            }
        }
        return diffs + lengthDiff;
    }
    // FORMATTING
    function offset(token, separator) {
        addFormatToken(token, 0, 0, function () {
            var offset = this.utcOffset(),
                sign = '+';
            if (offset < 0) {
                offset = -offset;
                sign = '-';
            }
            return (
                sign +
                zeroFill(~~(offset / 60), 2) +
                separator +
                zeroFill(~~offset % 60, 2)
            );
        });
    }
    offset('Z', ':');
    offset('ZZ', '');
    // PARSING
    addRegexToken('Z', matchShortOffset);
    addRegexToken('ZZ', matchShortOffset);
    addParseToken(['Z', 'ZZ'], function (input, array, config) {
        config._useUTC = true;
        config._tzm = offsetFromString(matchShortOffset, input);
    });
    // HELPERS
    // timezone chunker
    // '+10:00' > ['10',  '00']
    // '-1530'  > ['-15', '30']
    var chunkOffset = /([\+\-]|\d\d)/gi;
    function offsetFromString(matcher, string) {
        var matches = (string || '').match(matcher),
            chunk,
            parts,
            minutes;
        if (matches === null) {
            return null;
        }
        chunk = matches[matches.length - 1] || [];
        parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
        minutes = +(parts[1] * 60) + toInt(parts[2]);
        return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
    }
    // Return a moment from input, that is local/utc/zone equivalent to model.
    function cloneWithOffset(input, model) {
        var res, diff;
        if (model._isUTC) {
            res = model.clone();
            diff =
                (isMoment(input) || isDate(input)
                    ? input.valueOf()
                    : createLocal(input).valueOf()) - res.valueOf();
            // Use low-level api, because this fn is low-level api.
            res._d.setTime(res._d.valueOf() + diff);
            hooks.updateOffset(res, false);
            return res;
        } else {
            return createLocal(input).local();
        }
    }
    function getDateOffset(m) {
        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
        // https://github.com/moment/moment/pull/1871
        return -Math.round(m._d.getTimezoneOffset());
    }
    // HOOKS
    // This function will be called whenever a moment is mutated.
    // It is intended to keep the offset in sync with the timezone.
    hooks.updateOffset = function () {};
    // MOMENTS
    // keepLocalTime = true means only change the timezone, without
    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
    // +0200, so we adjust the time as needed, to be valid.
    // Keeping the time actually adds/subtracts (one hour)
    // from the actual represented time. That is why we call updateOffset
    // a second time. In case it wants us to change the offset again
    // _changeInProgress == true case, then we have to adjust, because
    // there is no such time in the given timezone.
    function getSetOffset(input, keepLocalTime, keepMinutes) {
        var offset = this._offset || 0,
            localAdjust;
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        if (input != null) {
            if (typeof input === 'string') {
                input = offsetFromString(matchShortOffset, input);
                if (input === null) {
                    return this;
                }
            } else if (Math.abs(input) < 16 && !keepMinutes) {
                input = input * 60;
            }
            if (!this._isUTC && keepLocalTime) {
                localAdjust = getDateOffset(this);
            }
            this._offset = input;
            this._isUTC = true;
            if (localAdjust != null) {
                this.add(localAdjust, 'm');
            }
            if (offset !== input) {
                if (!keepLocalTime || this._changeInProgress) {
                    addSubtract(
                        this,
                        createDuration(input - offset, 'm'),
                        1,
                        false
                    );
                } else if (!this._changeInProgress) {
                    this._changeInProgress = true;
                    hooks.updateOffset(this, true);
                    this._changeInProgress = null;
                }
            }
            return this;
        } else {
            return this._isUTC ? offset : getDateOffset(this);
        }
    }
    function getSetZone(input, keepLocalTime) {
        if (input != null) {
            if (typeof input !== 'string') {
                input = -input;
            }
            this.utcOffset(input, keepLocalTime);
            return this;
        } else {
            return -this.utcOffset();
        }
    }
    function setOffsetToUTC(keepLocalTime) {
        return this.utcOffset(0, keepLocalTime);
    }
    function setOffsetToLocal(keepLocalTime) {
        if (this._isUTC) {
            this.utcOffset(0, keepLocalTime);
            this._isUTC = false;
            if (keepLocalTime) {
                this.subtract(getDateOffset(this), 'm');
            }
        }
        return this;
    }
    function setOffsetToParsedOffset() {
        if (this._tzm != null) {
            this.utcOffset(this._tzm, false, true);
        } else if (typeof this._i === 'string') {
            var tZone = offsetFromString(matchOffset, this._i);
            if (tZone != null) {
                this.utcOffset(tZone);
            } else {
                this.utcOffset(0, true);
            }
        }
        return this;
    }
    function hasAlignedHourOffset(input) {
        if (!this.isValid()) {
            return false;
        }
        input = input ? createLocal(input).utcOffset() : 0;
        return (this.utcOffset() - input) % 60 === 0;
    }
    function isDaylightSavingTime() {
        return (
            this.utcOffset() > this.clone().month(0).utcOffset() ||
            this.utcOffset() > this.clone().month(5).utcOffset()
        );
    }
    function isDaylightSavingTimeShifted() {
        if (!isUndefined(this._isDSTShifted)) {
            return this._isDSTShifted;
        }
        var c = {},
            other;
        copyConfig(c, this);
        c = prepareConfig(c);
        if (c._a) {
            other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
            this._isDSTShifted =
                this.isValid() && compareArrays(c._a, other.toArray()) > 0;
        } else {
            this._isDSTShifted = false;
        }
        return this._isDSTShifted;
    }
    function isLocal() {
        return this.isValid() ? !this._isUTC : false;
    }
    function isUtcOffset() {
        return this.isValid() ? this._isUTC : false;
    }
    function isUtc() {
        return this.isValid() ? this._isUTC && this._offset === 0 : false;
    }
    // ASP.NET json date format regex
    var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,
        // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
        // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
        // and further modified to allow for strings containing both week and day
        isoRegex =
            /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
    function createDuration(input, key) {
        var duration = input,
            // matching against regexp is expensive, do it on demand
            match = null,
            sign,
            ret,
            diffRes;
        if (isDuration(input)) {
            duration = {
                ms: input._milliseconds,
                d: input._days,
                M: input._months,
            };
        } else if (isNumber(input) || !isNaN(+input)) {
            duration = {};
            if (key) {
                duration[key] = +input;
            } else {
                duration.milliseconds = +input;
            }
        } else if ((match = aspNetRegex.exec(input))) {
            sign = match[1] === '-' ? -1 : 1;
            duration = {
                y: 0,
                d: toInt(match[DATE]) * sign,
                h: toInt(match[HOUR]) * sign,
                m: toInt(match[MINUTE]) * sign,
                s: toInt(match[SECOND]) * sign,
                ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign, // the millisecond decimal point is included in the match
            };
        } else if ((match = isoRegex.exec(input))) {
            sign = match[1] === '-' ? -1 : 1;
            duration = {
                y: parseIso(match[2], sign),
                M: parseIso(match[3], sign),
                w: parseIso(match[4], sign),
                d: parseIso(match[5], sign),
                h: parseIso(match[6], sign),
                m: parseIso(match[7], sign),
                s: parseIso(match[8], sign),
            };
        } else if (duration == null) {
            // checks for null or undefined
            duration = {};
        } else if (
            typeof duration === 'object' &&
            ('from' in duration || 'to' in duration)
        ) {
            diffRes = momentsDifference(
                createLocal(duration.from),
                createLocal(duration.to)
            );
            duration = {};
            duration.ms = diffRes.milliseconds;
            duration.M = diffRes.months;
        }
        ret = new Duration(duration);
        if (isDuration(input) && hasOwnProp(input, '_locale')) {
            ret._locale = input._locale;
        }
        if (isDuration(input) && hasOwnProp(input, '_isValid')) {
            ret._isValid = input._isValid;
        }
        return ret;
    }
    createDuration.fn = Duration.prototype;
    createDuration.invalid = createInvalid$1;
    function parseIso(inp, sign) {
        // We'd normally use ~~inp for this, but unfortunately it also
        // converts floats to ints.
        // inp may be undefined, so careful calling replace on it.
        var res = inp && parseFloat(inp.replace(',', '.'));
        // apply sign while we're at it
        return (isNaN(res) ? 0 : res) * sign;
    }
    function positiveMomentsDifference(base, other) {
        var res = {};
        res.months =
            other.month() - base.month() + (other.year() - base.year()) * 12;
        if (base.clone().add(res.months, 'M').isAfter(other)) {
            --res.months;
        }
        res.milliseconds = +other - +base.clone().add(res.months, 'M');
        return res;
    }
    function momentsDifference(base, other) {
        var res;
        if (!(base.isValid() && other.isValid())) {
            return { milliseconds: 0, months: 0 };
        }
        other = cloneWithOffset(other, base);
        if (base.isBefore(other)) {
            res = positiveMomentsDifference(base, other);
        } else {
            res = positiveMomentsDifference(other, base);
            res.milliseconds = -res.milliseconds;
            res.months = -res.months;
        }
        return res;
    }
    // TODO: remove 'name' arg after deprecation is removed
    function createAdder(direction, name) {
        return function (val, period) {
            var dur, tmp;
            //invert the arguments, but complain about it
            if (period !== null && !isNaN(+period)) {
                deprecateSimple(
                    name,
                    'moment().' +
                        name +
                        '(period, number) is deprecated. Please use moment().' +
                        name +
                        '(number, period). ' +
                        'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'
                );
                tmp = val;
                val = period;
                period = tmp;
            }
            dur = createDuration(val, period);
            addSubtract(this, dur, direction);
            return this;
        };
    }
    function addSubtract(mom, duration, isAdding, updateOffset) {
        var milliseconds = duration._milliseconds,
            days = absRound(duration._days),
            months = absRound(duration._months);
        if (!mom.isValid()) {
            // No op
            return;
        }
        updateOffset = updateOffset == null ? true : updateOffset;
        if (months) {
            setMonth(mom, get(mom, 'Month') + months * isAdding);
        }
        if (days) {
            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
        }
        if (milliseconds) {
            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
        }
        if (updateOffset) {
            hooks.updateOffset(mom, days || months);
        }
    }
    var add = createAdder(1, 'add'),
        subtract = createAdder(-1, 'subtract');
    function isString(input) {
        return typeof input === 'string' || input instanceof String;
    }
    // type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined
    function isMomentInput(input) {
        return (
            isMoment(input) ||
            isDate(input) ||
            isString(input) ||
            isNumber(input) ||
            isNumberOrStringArray(input) ||
            isMomentInputObject(input) ||
            input === null ||
            input === undefined
        );
    }
    function isMomentInputObject(input) {
        var objectTest = isObject(input) && !isObjectEmpty(input),
            propertyTest = false,
            properties = [
                'years',
                'year',
                'y',
                'months',
                'month',
                'M',
                'days',
                'day',
                'd',
                'dates',
                'date',
                'D',
                'hours',
                'hour',
                'h',
                'minutes',
                'minute',
                'm',
                'seconds',
                'second',
                's',
                'milliseconds',
                'millisecond',
                'ms',
            ],
            i,
            property,
            propertyLen = properties.length;
        for (i = 0; i < propertyLen; i += 1) {
            property = properties[i];
            propertyTest = propertyTest || hasOwnProp(input, property);
        }
        return objectTest && propertyTest;
    }
    function isNumberOrStringArray(input) {
        var arrayTest = isArray(input),
            dataTypeTest = false;
        if (arrayTest) {
            dataTypeTest =
                input.filter(function (item) {
                    return !isNumber(item) && isString(input);
                }).length === 0;
        }
        return arrayTest && dataTypeTest;
    }
    function isCalendarSpec(input) {
        var objectTest = isObject(input) && !isObjectEmpty(input),
            propertyTest = false,
            properties = [
                'sameDay',
                'nextDay',
                'lastDay',
                'nextWeek',
                'lastWeek',
                'sameElse',
            ],
            i,
            property;
        for (i = 0; i < properties.length; i += 1) {
            property = properties[i];
            propertyTest = propertyTest || hasOwnProp(input, property);
        }
        return objectTest && propertyTest;
    }
    function getCalendarFormat(myMoment, now) {
        var diff = myMoment.diff(now, 'days', true);
        return diff < -6
            ? 'sameElse'
            : diff < -1
            ? 'lastWeek'
            : diff < 0
            ? 'lastDay'
            : diff < 1
            ? 'sameDay'
            : diff < 2
            ? 'nextDay'
            : diff < 7
            ? 'nextWeek'
            : 'sameElse';
    }
    function calendar$1(time, formats) {
        // Support for single parameter, formats only overload to the calendar function
        if (arguments.length === 1) {
            if (!arguments[0]) {
                time = undefined;
                formats = undefined;
            } else if (isMomentInput(arguments[0])) {
                time = arguments[0];
                formats = undefined;
            } else if (isCalendarSpec(arguments[0])) {
                formats = arguments[0];
                time = undefined;
            }
        }
        // We want to compare the start of today, vs this.
        // Getting start-of-today depends on whether we're local/utc/offset or not.
        var now = time || createLocal(),
            sod = cloneWithOffset(now, this).startOf('day'),
            format = hooks.calendarFormat(this, sod) || 'sameElse',
            output =
                formats &&
                (isFunction(formats[format])
                    ? formats[format].call(this, now)
                    : formats[format]);
        return this.format(
            output || this.localeData().calendar(format, this, createLocal(now))
        );
    }
    function clone() {
        return new Moment(this);
    }
    function isAfter(input, units) {
        var localInput = isMoment(input) ? input : createLocal(input);
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(units) || 'millisecond';
        if (units === 'millisecond') {
            return this.valueOf() > localInput.valueOf();
        } else {
            return localInput.valueOf() < this.clone().startOf(units).valueOf();
        }
    }
    function isBefore(input, units) {
        var localInput = isMoment(input) ? input : createLocal(input);
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(units) || 'millisecond';
        if (units === 'millisecond') {
            return this.valueOf() < localInput.valueOf();
        } else {
            return this.clone().endOf(units).valueOf() < localInput.valueOf();
        }
    }
    function isBetween(from, to, units, inclusivity) {
        var localFrom = isMoment(from) ? from : createLocal(from),
            localTo = isMoment(to) ? to : createLocal(to);
        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
            return false;
        }
        inclusivity = inclusivity || '()';
        return (
            (inclusivity[0] === '('
                ? this.isAfter(localFrom, units)
                : !this.isBefore(localFrom, units)) &&
            (inclusivity[1] === ')'
                ? this.isBefore(localTo, units)
                : !this.isAfter(localTo, units))
        );
    }
    function isSame(input, units) {
        var localInput = isMoment(input) ? input : createLocal(input),
            inputMs;
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(units) || 'millisecond';
        if (units === 'millisecond') {
            return this.valueOf() === localInput.valueOf();
        } else {
            inputMs = localInput.valueOf();
            return (
                this.clone().startOf(units).valueOf() <= inputMs &&
                inputMs <= this.clone().endOf(units).valueOf()
            );
        }
    }
    function isSameOrAfter(input, units) {
        return this.isSame(input, units) || this.isAfter(input, units);
    }
    function isSameOrBefore(input, units) {
        return this.isSame(input, units) || this.isBefore(input, units);
    }
    function diff(input, units, asFloat) {
        var that, zoneDelta, output;
        if (!this.isValid()) {
            return NaN;
        }
        that = cloneWithOffset(input, this);
        if (!that.isValid()) {
            return NaN;
        }
        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
        units = normalizeUnits(units);
        switch (units) {
            case 'year':
                output = monthDiff(this, that) / 12;
                break;
            case 'month':
                output = monthDiff(this, that);
                break;
            case 'quarter':
                output = monthDiff(this, that) / 3;
                break;
            case 'second':
                output = (this - that) / 1e3;
                break; // 1000
            case 'minute':
                output = (this - that) / 6e4;
                break; // 1000 * 60
            case 'hour':
                output = (this - that) / 36e5;
                break; // 1000 * 60 * 60
            case 'day':
                output = (this - that - zoneDelta) / 864e5;
                break; // 1000 * 60 * 60 * 24, negate dst
            case 'week':
                output = (this - that - zoneDelta) / 6048e5;
                break; // 1000 * 60 * 60 * 24 * 7, negate dst
            default:
                output = this - that;
        }
        return asFloat ? output : absFloor(output);
    }
    function monthDiff(a, b) {
        if (a.date() < b.date()) {
            // end-of-month calculations work correct when the start month has more
            // days than the end month.
            return -monthDiff(b, a);
        }
        // difference in months
        var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
            // b is in (anchor - 1 month, anchor + 1 month)
            anchor = a.clone().add(wholeMonthDiff, 'months'),
            anchor2,
            adjust;
        if (b - anchor < 0) {
            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
            // linear across the month
            adjust = (b - anchor) / (anchor - anchor2);
        } else {
            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
            // linear across the month
            adjust = (b - anchor) / (anchor2 - anchor);
        }
        //check for negative zero, return zero if negative zero
        return -(wholeMonthDiff + adjust) || 0;
    }
    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
    function toString() {
        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
    }
    function toISOString(keepOffset) {
        if (!this.isValid()) {
            return null;
        }
        var utc = keepOffset !== true,
            m = utc ? this.clone().utc() : this;
        if (m.year() < 0 || m.year() > 9999) {
            return formatMoment(
                m,
                utc
                    ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'
                    : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'
            );
        }
        if (isFunction(Date.prototype.toISOString)) {
            // native implementation is ~50x faster, use it when we can
            if (utc) {
                return this.toDate().toISOString();
            } else {
                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000)
                    .toISOString()
                    .replace('Z', formatMoment(m, 'Z'));
            }
        }
        return formatMoment(
            m,
            utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'
        );
    }
    /**
     * Return a human readable representation of a moment that can
     * also be evaluated to get a new moment which is the same
     *
     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
     */
    function inspect() {
        if (!this.isValid()) {
            return 'moment.invalid(/* ' + this._i + ' */)';
        }
        var func = 'moment',
            zone = '',
            prefix,
            year,
            datetime,
            suffix;
        if (!this.isLocal()) {
            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
            zone = 'Z';
        }
        prefix = '[' + func + '("]';
        year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
        datetime = '-MM-DD[T]HH:mm:ss.SSS';
        suffix = zone + '[")]';
        return this.format(prefix + year + datetime + suffix);
    }
    function format(inputString) {
        if (!inputString) {
            inputString = this.isUtc()
                ? hooks.defaultFormatUtc
                : hooks.defaultFormat;
        }
        var output = formatMoment(this, inputString);
        return this.localeData().postformat(output);
    }
    function from(time, withoutSuffix) {
        if (
            this.isValid() &&
            ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
        ) {
            return createDuration({ to: this, from: time })
                .locale(this.locale())
                .humanize(!withoutSuffix);
        } else {
            return this.localeData().invalidDate();
        }
    }
    function fromNow(withoutSuffix) {
        return this.from(createLocal(), withoutSuffix);
    }
    function to(time, withoutSuffix) {
        if (
            this.isValid() &&
            ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
        ) {
            return createDuration({ from: this, to: time })
                .locale(this.locale())
                .humanize(!withoutSuffix);
        } else {
            return this.localeData().invalidDate();
        }
    }
    function toNow(withoutSuffix) {
        return this.to(createLocal(), withoutSuffix);
    }
    // If passed a locale key, it will set the locale for this
    // instance.  Otherwise, it will return the locale configuration
    // variables for this instance.
    function locale(key) {
        var newLocaleData;
        if (key === undefined) {
            return this._locale._abbr;
        } else {
            newLocaleData = getLocale(key);
            if (newLocaleData != null) {
                this._locale = newLocaleData;
            }
            return this;
        }
    }
    var lang = deprecate(
        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
        function (key) {
            if (key === undefined) {
                return this.localeData();
            } else {
                return this.locale(key);
            }
        }
    );
    function localeData() {
        return this._locale;
    }
    var MS_PER_SECOND = 1000,
        MS_PER_MINUTE = 60 * MS_PER_SECOND,
        MS_PER_HOUR = 60 * MS_PER_MINUTE,
        MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
    // actual modulo - handles negative numbers (for dates before 1970):
    function mod$1(dividend, divisor) {
        return ((dividend % divisor) + divisor) % divisor;
    }
    function localStartOfDate(y, m, d) {
        // the date constructor remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0) {
            // preserve leap years using a full 400 year cycle, then reset
            return new Date(y + 400, m, d) - MS_PER_400_YEARS;
        } else {
            return new Date(y, m, d).valueOf();
        }
    }
    function utcStartOfDate(y, m, d) {
        // Date.UTC remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0) {
            // preserve leap years using a full 400 year cycle, then reset
            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
        } else {
            return Date.UTC(y, m, d);
        }
    }
    function startOf(units) {
        var time, startOfDate;
        units = normalizeUnits(units);
        if (units === undefined || units === 'millisecond' || !this.isValid()) {
            return this;
        }
        startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
        switch (units) {
            case 'year':
                time = startOfDate(this.year(), 0, 1);
                break;
            case 'quarter':
                time = startOfDate(
                    this.year(),
                    this.month() - (this.month() % 3),
                    1
                );
                break;
            case 'month':
                time = startOfDate(this.year(), this.month(), 1);
                break;
            case 'week':
                time = startOfDate(
                    this.year(),
                    this.month(),
                    this.date() - this.weekday()
                );
                break;
            case 'isoWeek':
                time = startOfDate(
                    this.year(),
                    this.month(),
                    this.date() - (this.isoWeekday() - 1)
                );
                break;
            case 'day':
            case 'date':
                time = startOfDate(this.year(), this.month(), this.date());
                break;
            case 'hour':
                time = this._d.valueOf();
                time -= mod$1(
                    time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
                    MS_PER_HOUR
                );
                break;
            case 'minute':
                time = this._d.valueOf();
                time -= mod$1(time, MS_PER_MINUTE);
                break;
            case 'second':
                time = this._d.valueOf();
                time -= mod$1(time, MS_PER_SECOND);
                break;
        }
        this._d.setTime(time);
        hooks.updateOffset(this, true);
        return this;
    }
    function endOf(units) {
        var time, startOfDate;
        units = normalizeUnits(units);
        if (units === undefined || units === 'millisecond' || !this.isValid()) {
            return this;
        }
        startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
        switch (units) {
            case 'year':
                time = startOfDate(this.year() + 1, 0, 1) - 1;
                break;
            case 'quarter':
                time =
                    startOfDate(
                        this.year(),
                        this.month() - (this.month() % 3) + 3,
                        1
                    ) - 1;
                break;
            case 'month':
                time = startOfDate(this.year(), this.month() + 1, 1) - 1;
                break;
            case 'week':
                time =
                    startOfDate(
                        this.year(),
                        this.month(),
                        this.date() - this.weekday() + 7
                    ) - 1;
                break;
            case 'isoWeek':
                time =
                    startOfDate(
                        this.year(),
                        this.month(),
                        this.date() - (this.isoWeekday() - 1) + 7
                    ) - 1;
                break;
            case 'day':
            case 'date':
                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
                break;
            case 'hour':
                time = this._d.valueOf();
                time +=
                    MS_PER_HOUR -
                    mod$1(
                        time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
                        MS_PER_HOUR
                    ) -
                    1;
                break;
            case 'minute':
                time = this._d.valueOf();
                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
                break;
            case 'second':
                time = this._d.valueOf();
                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
                break;
        }
        this._d.setTime(time);
        hooks.updateOffset(this, true);
        return this;
    }
    function valueOf() {
        return this._d.valueOf() - (this._offset || 0) * 60000;
    }
    function unix() {
        return Math.floor(this.valueOf() / 1000);
    }
    function toDate() {
        return new Date(this.valueOf());
    }
    function toArray() {
        var m = this;
        return [
            m.year(),
            m.month(),
            m.date(),
            m.hour(),
            m.minute(),
            m.second(),
            m.millisecond(),
        ];
    }
    function toObject() {
        var m = this;
        return {
            years: m.year(),
            months: m.month(),
            date: m.date(),
            hours: m.hours(),
            minutes: m.minutes(),
            seconds: m.seconds(),
            milliseconds: m.milliseconds(),
        };
    }
    function toJSON() {
        // new Date(NaN).toJSON() === null
        return this.isValid() ? this.toISOString() : null;
    }
    function isValid$2() {
        return isValid(this);
    }
    function parsingFlags() {
        return extend({}, getParsingFlags(this));
    }
    function invalidAt() {
        return getParsingFlags(this).overflow;
    }
    function creationData() {
        return {
            input: this._i,
            format: this._f,
            locale: this._locale,
            isUTC: this._isUTC,
            strict: this._strict,
        };
    }
    addFormatToken('N', 0, 0, 'eraAbbr');
    addFormatToken('NN', 0, 0, 'eraAbbr');
    addFormatToken('NNN', 0, 0, 'eraAbbr');
    addFormatToken('NNNN', 0, 0, 'eraName');
    addFormatToken('NNNNN', 0, 0, 'eraNarrow');
    addFormatToken('y', ['y', 1], 'yo', 'eraYear');
    addFormatToken('y', ['yy', 2], 0, 'eraYear');
    addFormatToken('y', ['yyy', 3], 0, 'eraYear');
    addFormatToken('y', ['yyyy', 4], 0, 'eraYear');
    addRegexToken('N', matchEraAbbr);
    addRegexToken('NN', matchEraAbbr);
    addRegexToken('NNN', matchEraAbbr);
    addRegexToken('NNNN', matchEraName);
    addRegexToken('NNNNN', matchEraNarrow);
    addParseToken(
        ['N', 'NN', 'NNN', 'NNNN', 'NNNNN'],
        function (input, array, config, token) {
            var era = config._locale.erasParse(input, token, config._strict);
            if (era) {
                getParsingFlags(config).era = era;
            } else {
                getParsingFlags(config).invalidEra = input;
            }
        }
    );
    addRegexToken('y', matchUnsigned);
    addRegexToken('yy', matchUnsigned);
    addRegexToken('yyy', matchUnsigned);
    addRegexToken('yyyy', matchUnsigned);
    addRegexToken('yo', matchEraYearOrdinal);
    addParseToken(['y', 'yy', 'yyy', 'yyyy'], YEAR);
    addParseToken(['yo'], function (input, array, config, token) {
        var match;
        if (config._locale._eraYearOrdinalRegex) {
            match = input.match(config._locale._eraYearOrdinalRegex);
        }
        if (config._locale.eraYearOrdinalParse) {
            array[YEAR] = config._locale.eraYearOrdinalParse(input, match);
        } else {
            array[YEAR] = parseInt(input, 10);
        }
    });
    function localeEras(m, format) {
        var i,
            l,
            date,
            eras = this._eras || getLocale('en')._eras;
        for (i = 0, l = eras.length; i < l; ++i) {
            switch (typeof eras[i].since) {
                case 'string':
                    // truncate time
                    date = hooks(eras[i].since).startOf('day');
                    eras[i].since = date.valueOf();
                    break;
            }
            switch (typeof eras[i].until) {
                case 'undefined':
                    eras[i].until = +Infinity;
                    break;
                case 'string':
                    // truncate time
                    date = hooks(eras[i].until).startOf('day').valueOf();
                    eras[i].until = date.valueOf();
                    break;
            }
        }
        return eras;
    }
    function localeErasParse(eraName, format, strict) {
        var i,
            l,
            eras = this.eras(),
            name,
            abbr,
            narrow;
        eraName = eraName.toUpperCase();
        for (i = 0, l = eras.length; i < l; ++i) {
            name = eras[i].name.toUpperCase();
            abbr = eras[i].abbr.toUpperCase();
            narrow = eras[i].narrow.toUpperCase();
            if (strict) {
                switch (format) {
                    case 'N':
                    case 'NN':
                    case 'NNN':
                        if (abbr === eraName) {
                            return eras[i];
                        }
                        break;
                    case 'NNNN':
                        if (name === eraName) {
                            return eras[i];
                        }
                        break;
                    case 'NNNNN':
                        if (narrow === eraName) {
                            return eras[i];
                        }
                        break;
                }
            } else if ([name, abbr, narrow].indexOf(eraName) >= 0) {
                return eras[i];
            }
        }
    }
    function localeErasConvertYear(era, year) {
        var dir = era.since <= era.until ? +1 : -1;
        if (year === undefined) {
            return hooks(era.since).year();
        } else {
            return hooks(era.since).year() + (year - era.offset) * dir;
        }
    }
    function getEraName() {
        var i,
            l,
            val,
            eras = this.localeData().eras();
        for (i = 0, l = eras.length; i < l; ++i) {
            // truncate time
            val = this.clone().startOf('day').valueOf();
            if (eras[i].since <= val && val <= eras[i].until) {
                return eras[i].name;
            }
            if (eras[i].until <= val && val <= eras[i].since) {
                return eras[i].name;
            }
        }
        return '';
    }
    function getEraNarrow() {
        var i,
            l,
            val,
            eras = this.localeData().eras();
        for (i = 0, l = eras.length; i < l; ++i) {
            // truncate time
            val = this.clone().startOf('day').valueOf();
            if (eras[i].since <= val && val <= eras[i].until) {
                return eras[i].narrow;
            }
            if (eras[i].until <= val && val <= eras[i].since) {
                return eras[i].narrow;
            }
        }
        return '';
    }
    function getEraAbbr() {
        var i,
            l,
            val,
            eras = this.localeData().eras();
        for (i = 0, l = eras.length; i < l; ++i) {
            // truncate time
            val = this.clone().startOf('day').valueOf();
            if (eras[i].since <= val && val <= eras[i].until) {
                return eras[i].abbr;
            }
            if (eras[i].until <= val && val <= eras[i].since) {
                return eras[i].abbr;
            }
        }
        return '';
    }
    function getEraYear() {
        var i,
            l,
            dir,
            val,
            eras = this.localeData().eras();
        for (i = 0, l = eras.length; i < l; ++i) {
            dir = eras[i].since <= eras[i].until ? +1 : -1;
            // truncate time
            val = this.clone().startOf('day').valueOf();
            if (
                (eras[i].since <= val && val <= eras[i].until) ||
                (eras[i].until <= val && val <= eras[i].since)
            ) {
                return (
                    (this.year() - hooks(eras[i].since).year()) * dir +
                    eras[i].offset
                );
            }
        }
        return this.year();
    }
    function erasNameRegex(isStrict) {
        if (!hasOwnProp(this, '_erasNameRegex')) {
            computeErasParse.call(this);
        }
        return isStrict ? this._erasNameRegex : this._erasRegex;
    }
    function erasAbbrRegex(isStrict) {
        if (!hasOwnProp(this, '_erasAbbrRegex')) {
            computeErasParse.call(this);
        }
        return isStrict ? this._erasAbbrRegex : this._erasRegex;
    }
    function erasNarrowRegex(isStrict) {
        if (!hasOwnProp(this, '_erasNarrowRegex')) {
            computeErasParse.call(this);
        }
        return isStrict ? this._erasNarrowRegex : this._erasRegex;
    }
    function matchEraAbbr(isStrict, locale) {
        return locale.erasAbbrRegex(isStrict);
    }
    function matchEraName(isStrict, locale) {
        return locale.erasNameRegex(isStrict);
    }
    function matchEraNarrow(isStrict, locale) {
        return locale.erasNarrowRegex(isStrict);
    }
    function matchEraYearOrdinal(isStrict, locale) {
        return locale._eraYearOrdinalRegex || matchUnsigned;
    }
    function computeErasParse() {
        var abbrPieces = [],
            namePieces = [],
            narrowPieces = [],
            mixedPieces = [],
            i,
            l,
            eras = this.eras();
        for (i = 0, l = eras.length; i < l; ++i) {
            namePieces.push(regexEscape(eras[i].name));
            abbrPieces.push(regexEscape(eras[i].abbr));
            narrowPieces.push(regexEscape(eras[i].narrow));
            mixedPieces.push(regexEscape(eras[i].name));
            mixedPieces.push(regexEscape(eras[i].abbr));
            mixedPieces.push(regexEscape(eras[i].narrow));
        }
        this._erasRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
        this._erasNameRegex = new RegExp('^(' + namePieces.join('|') + ')', 'i');
        this._erasAbbrRegex = new RegExp('^(' + abbrPieces.join('|') + ')', 'i');
        this._erasNarrowRegex = new RegExp(
            '^(' + narrowPieces.join('|') + ')',
            'i'
        );
    }
    // FORMATTING
    addFormatToken(0, ['gg', 2], 0, function () {
        return this.weekYear() % 100;
    });
    addFormatToken(0, ['GG', 2], 0, function () {
        return this.isoWeekYear() % 100;
    });
    function addWeekYearFormatToken(token, getter) {
        addFormatToken(0, [token, token.length], 0, getter);
    }
    addWeekYearFormatToken('gggg', 'weekYear');
    addWeekYearFormatToken('ggggg', 'weekYear');
    addWeekYearFormatToken('GGGG', 'isoWeekYear');
    addWeekYearFormatToken('GGGGG', 'isoWeekYear');
    // ALIASES
    addUnitAlias('weekYear', 'gg');
    addUnitAlias('isoWeekYear', 'GG');
    // PRIORITY
    addUnitPriority('weekYear', 1);
    addUnitPriority('isoWeekYear', 1);
    // PARSING
    addRegexToken('G', matchSigned);
    addRegexToken('g', matchSigned);
    addRegexToken('GG', match1to2, match2);
    addRegexToken('gg', match1to2, match2);
    addRegexToken('GGGG', match1to4, match4);
    addRegexToken('gggg', match1to4, match4);
    addRegexToken('GGGGG', match1to6, match6);
    addRegexToken('ggggg', match1to6, match6);
    addWeekParseToken(
        ['gggg', 'ggggg', 'GGGG', 'GGGGG'],
        function (input, week, config, token) {
            week[token.substr(0, 2)] = toInt(input);
        }
    );
    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
        week[token] = hooks.parseTwoDigitYear(input);
    });
    // MOMENTS
    function getSetWeekYear(input) {
        return getSetWeekYearHelper.call(
            this,
            input,
            this.week(),
            this.weekday(),
            this.localeData()._week.dow,
            this.localeData()._week.doy
        );
    }
    function getSetISOWeekYear(input) {
        return getSetWeekYearHelper.call(
            this,
            input,
            this.isoWeek(),
            this.isoWeekday(),
            1,
            4
        );
    }
    function getISOWeeksInYear() {
        return weeksInYear(this.year(), 1, 4);
    }
    function getISOWeeksInISOWeekYear() {
        return weeksInYear(this.isoWeekYear(), 1, 4);
    }
    function getWeeksInYear() {
        var weekInfo = this.localeData()._week;
        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
    }
    function getWeeksInWeekYear() {
        var weekInfo = this.localeData()._week;
        return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy);
    }
    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
        var weeksTarget;
        if (input == null) {
            return weekOfYear(this, dow, doy).year;
        } else {
            weeksTarget = weeksInYear(input, dow, doy);
            if (week > weeksTarget) {
                week = weeksTarget;
            }
            return setWeekAll.call(this, input, week, weekday, dow, doy);
        }
    }
    function setWeekAll(weekYear, week, weekday, dow, doy) {
        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
        this.year(date.getUTCFullYear());
        this.month(date.getUTCMonth());
        this.date(date.getUTCDate());
        return this;
    }
    // FORMATTING
    addFormatToken('Q', 0, 'Qo', 'quarter');
    // ALIASES
    addUnitAlias('quarter', 'Q');
    // PRIORITY
    addUnitPriority('quarter', 7);
    // PARSING
    addRegexToken('Q', match1);
    addParseToken('Q', function (input, array) {
        array[MONTH] = (toInt(input) - 1) * 3;
    });
    // MOMENTS
    function getSetQuarter(input) {
        return input == null
            ? Math.ceil((this.month() + 1) / 3)
            : this.month((input - 1) * 3 + (this.month() % 3));
    }
    // FORMATTING
    addFormatToken('D', ['DD', 2], 'Do', 'date');
    // ALIASES
    addUnitAlias('date', 'D');
    // PRIORITY
    addUnitPriority('date', 9);
    // PARSING
    addRegexToken('D', match1to2);
    addRegexToken('DD', match1to2, match2);
    addRegexToken('Do', function (isStrict, locale) {
        // TODO: Remove "ordinalParse" fallback in next major release.
        return isStrict
            ? locale._dayOfMonthOrdinalParse || locale._ordinalParse
            : locale._dayOfMonthOrdinalParseLenient;
    });
    addParseToken(['D', 'DD'], DATE);
    addParseToken('Do', function (input, array) {
        array[DATE] = toInt(input.match(match1to2)[0]);
    });
    // MOMENTS
    var getSetDayOfMonth = makeGetSet('Date', true);
    // FORMATTING
    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
    // ALIASES
    addUnitAlias('dayOfYear', 'DDD');
    // PRIORITY
    addUnitPriority('dayOfYear', 4);
    // PARSING
    addRegexToken('DDD', match1to3);
    addRegexToken('DDDD', match3);
    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
        config._dayOfYear = toInt(input);
    });
    // HELPERS
    // MOMENTS
    function getSetDayOfYear(input) {
        var dayOfYear =
            Math.round(
                (this.clone().startOf('day') - this.clone().startOf('year')) / 864e5
            ) + 1;
        return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
    }
    // FORMATTING
    addFormatToken('m', ['mm', 2], 0, 'minute');
    // ALIASES
    addUnitAlias('minute', 'm');
    // PRIORITY
    addUnitPriority('minute', 14);
    // PARSING
    addRegexToken('m', match1to2);
    addRegexToken('mm', match1to2, match2);
    addParseToken(['m', 'mm'], MINUTE);
    // MOMENTS
    var getSetMinute = makeGetSet('Minutes', false);
    // FORMATTING
    addFormatToken('s', ['ss', 2], 0, 'second');
    // ALIASES
    addUnitAlias('second', 's');
    // PRIORITY
    addUnitPriority('second', 15);
    // PARSING
    addRegexToken('s', match1to2);
    addRegexToken('ss', match1to2, match2);
    addParseToken(['s', 'ss'], SECOND);
    // MOMENTS
    var getSetSecond = makeGetSet('Seconds', false);
    // FORMATTING
    addFormatToken('S', 0, 0, function () {
        return ~~(this.millisecond() / 100);
    });
    addFormatToken(0, ['SS', 2], 0, function () {
        return ~~(this.millisecond() / 10);
    });
    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
    addFormatToken(0, ['SSSS', 4], 0, function () {
        return this.millisecond() * 10;
    });
    addFormatToken(0, ['SSSSS', 5], 0, function () {
        return this.millisecond() * 100;
    });
    addFormatToken(0, ['SSSSSS', 6], 0, function () {
        return this.millisecond() * 1000;
    });
    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
        return this.millisecond() * 10000;
    });
    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
        return this.millisecond() * 100000;
    });
    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
        return this.millisecond() * 1000000;
    });
    // ALIASES
    addUnitAlias('millisecond', 'ms');
    // PRIORITY
    addUnitPriority('millisecond', 16);
    // PARSING
    addRegexToken('S', match1to3, match1);
    addRegexToken('SS', match1to3, match2);
    addRegexToken('SSS', match1to3, match3);
    var token, getSetMillisecond;
    for (token = 'SSSS'; token.length <= 9; token += 'S') {
        addRegexToken(token, matchUnsigned);
    }
    function parseMs(input, array) {
        array[MILLISECOND] = toInt(('0.' + input) * 1000);
    }
    for (token = 'S'; token.length <= 9; token += 'S') {
        addParseToken(token, parseMs);
    }
    getSetMillisecond = makeGetSet('Milliseconds', false);
    // FORMATTING
    addFormatToken('z', 0, 0, 'zoneAbbr');
    addFormatToken('zz', 0, 0, 'zoneName');
    // MOMENTS
    function getZoneAbbr() {
        return this._isUTC ? 'UTC' : '';
    }
    function getZoneName() {
        return this._isUTC ? 'Coordinated Universal Time' : '';
    }
    var proto = Moment.prototype;
    proto.add = add;
    proto.calendar = calendar$1;
    proto.clone = clone;
    proto.diff = diff;
    proto.endOf = endOf;
    proto.format = format;
    proto.from = from;
    proto.fromNow = fromNow;
    proto.to = to;
    proto.toNow = toNow;
    proto.get = stringGet;
    proto.invalidAt = invalidAt;
    proto.isAfter = isAfter;
    proto.isBefore = isBefore;
    proto.isBetween = isBetween;
    proto.isSame = isSame;
    proto.isSameOrAfter = isSameOrAfter;
    proto.isSameOrBefore = isSameOrBefore;
    proto.isValid = isValid$2;
    proto.lang = lang;
    proto.locale = locale;
    proto.localeData = localeData;
    proto.max = prototypeMax;
    proto.min = prototypeMin;
    proto.parsingFlags = parsingFlags;
    proto.set = stringSet;
    proto.startOf = startOf;
    proto.subtract = subtract;
    proto.toArray = toArray;
    proto.toObject = toObject;
    proto.toDate = toDate;
    proto.toISOString = toISOString;
    proto.inspect = inspect;
    if (typeof Symbol !== 'undefined' && Symbol.for != null) {
        proto[Symbol.for('nodejs.util.inspect.custom')] = function () {
            return 'Moment<' + this.format() + '>';
        };
    }
    proto.toJSON = toJSON;
    proto.toString = toString;
    proto.unix = unix;
    proto.valueOf = valueOf;
    proto.creationData = creationData;
    proto.eraName = getEraName;
    proto.eraNarrow = getEraNarrow;
    proto.eraAbbr = getEraAbbr;
    proto.eraYear = getEraYear;
    proto.year = getSetYear;
    proto.isLeapYear = getIsLeapYear;
    proto.weekYear = getSetWeekYear;
    proto.isoWeekYear = getSetISOWeekYear;
    proto.quarter = proto.quarters = getSetQuarter;
    proto.month = getSetMonth;
    proto.daysInMonth = getDaysInMonth;
    proto.week = proto.weeks = getSetWeek;
    proto.isoWeek = proto.isoWeeks = getSetISOWeek;
    proto.weeksInYear = getWeeksInYear;
    proto.weeksInWeekYear = getWeeksInWeekYear;
    proto.isoWeeksInYear = getISOWeeksInYear;
    proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear;
    proto.date = getSetDayOfMonth;
    proto.day = proto.days = getSetDayOfWeek;
    proto.weekday = getSetLocaleDayOfWeek;
    proto.isoWeekday = getSetISODayOfWeek;
    proto.dayOfYear = getSetDayOfYear;
    proto.hour = proto.hours = getSetHour;
    proto.minute = proto.minutes = getSetMinute;
    proto.second = proto.seconds = getSetSecond;
    proto.millisecond = proto.milliseconds = getSetMillisecond;
    proto.utcOffset = getSetOffset;
    proto.utc = setOffsetToUTC;
    proto.local = setOffsetToLocal;
    proto.parseZone = setOffsetToParsedOffset;
    proto.hasAlignedHourOffset = hasAlignedHourOffset;
    proto.isDST = isDaylightSavingTime;
    proto.isLocal = isLocal;
    proto.isUtcOffset = isUtcOffset;
    proto.isUtc = isUtc;
    proto.isUTC = isUtc;
    proto.zoneAbbr = getZoneAbbr;
    proto.zoneName = getZoneName;
    proto.dates = deprecate(
        'dates accessor is deprecated. Use date instead.',
        getSetDayOfMonth
    );
    proto.months = deprecate(
        'months accessor is deprecated. Use month instead',
        getSetMonth
    );
    proto.years = deprecate(
        'years accessor is deprecated. Use year instead',
        getSetYear
    );
    proto.zone = deprecate(
        'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/',
        getSetZone
    );
    proto.isDSTShifted = deprecate(
        'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information',
        isDaylightSavingTimeShifted
    );
    function createUnix(input) {
        return createLocal(input * 1000);
    }
    function createInZone() {
        return createLocal.apply(null, arguments).parseZone();
    }
    function preParsePostFormat(string) {
        return string;
    }
    var proto$1 = Locale.prototype;
    proto$1.calendar = calendar;
    proto$1.longDateFormat = longDateFormat;
    proto$1.invalidDate = invalidDate;
    proto$1.ordinal = ordinal;
    proto$1.preparse = preParsePostFormat;
    proto$1.postformat = preParsePostFormat;
    proto$1.relativeTime = relativeTime;
    proto$1.pastFuture = pastFuture;
    proto$1.set = set;
    proto$1.eras = localeEras;
    proto$1.erasParse = localeErasParse;
    proto$1.erasConvertYear = localeErasConvertYear;
    proto$1.erasAbbrRegex = erasAbbrRegex;
    proto$1.erasNameRegex = erasNameRegex;
    proto$1.erasNarrowRegex = erasNarrowRegex;
    proto$1.months = localeMonths;
    proto$1.monthsShort = localeMonthsShort;
    proto$1.monthsParse = localeMonthsParse;
    proto$1.monthsRegex = monthsRegex;
    proto$1.monthsShortRegex = monthsShortRegex;
    proto$1.week = localeWeek;
    proto$1.firstDayOfYear = localeFirstDayOfYear;
    proto$1.firstDayOfWeek = localeFirstDayOfWeek;
    proto$1.weekdays = localeWeekdays;
    proto$1.weekdaysMin = localeWeekdaysMin;
    proto$1.weekdaysShort = localeWeekdaysShort;
    proto$1.weekdaysParse = localeWeekdaysParse;
    proto$1.weekdaysRegex = weekdaysRegex;
    proto$1.weekdaysShortRegex = weekdaysShortRegex;
    proto$1.weekdaysMinRegex = weekdaysMinRegex;
    proto$1.isPM = localeIsPM;
    proto$1.meridiem = localeMeridiem;
    function get$1(format, index, field, setter) {
        var locale = getLocale(),
            utc = createUTC().set(setter, index);
        return locale[field](utc, format);
    }
    function listMonthsImpl(format, index, field) {
        if (isNumber(format)) {
            index = format;
            format = undefined;
        }
        format = format || '';
        if (index != null) {
            return get$1(format, index, field, 'month');
        }
        var i,
            out = [];
        for (i = 0; i < 12; i++) {
            out[i] = get$1(format, i, field, 'month');
        }
        return out;
    }
    // ()
    // (5)
    // (fmt, 5)
    // (fmt)
    // (true)
    // (true, 5)
    // (true, fmt, 5)
    // (true, fmt)
    function listWeekdaysImpl(localeSorted, format, index, field) {
        if (typeof localeSorted === 'boolean') {
            if (isNumber(format)) {
                index = format;
                format = undefined;
            }
            format = format || '';
        } else {
            format = localeSorted;
            index = format;
            localeSorted = false;
            if (isNumber(format)) {
                index = format;
                format = undefined;
            }
            format = format || '';
        }
        var locale = getLocale(),
            shift = localeSorted ? locale._week.dow : 0,
            i,
            out = [];
        if (index != null) {
            return get$1(format, (index + shift) % 7, field, 'day');
        }
        for (i = 0; i < 7; i++) {
            out[i] = get$1(format, (i + shift) % 7, field, 'day');
        }
        return out;
    }
    function listMonths(format, index) {
        return listMonthsImpl(format, index, 'months');
    }
    function listMonthsShort(format, index) {
        return listMonthsImpl(format, index, 'monthsShort');
    }
    function listWeekdays(localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
    }
    function listWeekdaysShort(localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
    }
    function listWeekdaysMin(localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
    }
    getSetGlobalLocale('en', {
        eras: [
            {
                since: '0001-01-01',
                until: +Infinity,
                offset: 1,
                name: 'Anno Domini',
                narrow: 'AD',
                abbr: 'AD',
            },
            {
                since: '0000-12-31',
                until: -Infinity,
                offset: 1,
                name: 'Before Christ',
                narrow: 'BC',
                abbr: 'BC',
            },
        ],
        dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
        ordinal: function (number) {
            var b = number % 10,
                output =
                    toInt((number % 100) / 10) === 1
                        ? 'th'
                        : b === 1
                        ? 'st'
                        : b === 2
                        ? 'nd'
                        : b === 3
                        ? 'rd'
                        : 'th';
            return number + output;
        },
    });
    // Side effect imports
    hooks.lang = deprecate(
        'moment.lang is deprecated. Use moment.locale instead.',
        getSetGlobalLocale
    );
    hooks.langData = deprecate(
        'moment.langData is deprecated. Use moment.localeData instead.',
        getLocale
    );
    var mathAbs = Math.abs;
    function abs() {
        var data = this._data;
        this._milliseconds = mathAbs(this._milliseconds);
        this._days = mathAbs(this._days);
        this._months = mathAbs(this._months);
        data.milliseconds = mathAbs(data.milliseconds);
        data.seconds = mathAbs(data.seconds);
        data.minutes = mathAbs(data.minutes);
        data.hours = mathAbs(data.hours);
        data.months = mathAbs(data.months);
        data.years = mathAbs(data.years);
        return this;
    }
    function addSubtract$1(duration, input, value, direction) {
        var other = createDuration(input, value);
        duration._milliseconds += direction * other._milliseconds;
        duration._days += direction * other._days;
        duration._months += direction * other._months;
        return duration._bubble();
    }
    // supports only 2.0-style add(1, 's') or add(duration)
    function add$1(input, value) {
        return addSubtract$1(this, input, value, 1);
    }
    // supports only 2.0-style subtract(1, 's') or subtract(duration)
    function subtract$1(input, value) {
        return addSubtract$1(this, input, value, -1);
    }
    function absCeil(number) {
        if (number < 0) {
            return Math.floor(number);
        } else {
            return Math.ceil(number);
        }
    }
    function bubble() {
        var milliseconds = this._milliseconds,
            days = this._days,
            months = this._months,
            data = this._data,
            seconds,
            minutes,
            hours,
            years,
            monthsFromDays;
        // if we have a mix of positive and negative values, bubble down first
        // check: https://github.com/moment/moment/issues/2166
        if (
            !(
                (milliseconds >= 0 && days >= 0 && months >= 0) ||
                (milliseconds <= 0 && days <= 0 && months <= 0)
            )
        ) {
            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
            days = 0;
            months = 0;
        }
        // The following code bubbles up values, see the tests for
        // examples of what that means.
        data.milliseconds = milliseconds % 1000;
        seconds = absFloor(milliseconds / 1000);
        data.seconds = seconds % 60;
        minutes = absFloor(seconds / 60);
        data.minutes = minutes % 60;
        hours = absFloor(minutes / 60);
        data.hours = hours % 24;
        days += absFloor(hours / 24);
        // convert days to months
        monthsFromDays = absFloor(daysToMonths(days));
        months += monthsFromDays;
        days -= absCeil(monthsToDays(monthsFromDays));
        // 12 months -> 1 year
        years = absFloor(months / 12);
        months %= 12;
        data.days = days;
        data.months = months;
        data.years = years;
        return this;
    }
    function daysToMonths(days) {
        // 400 years have 146097 days (taking into account leap year rules)
        // 400 years have 12 months === 4800
        return (days * 4800) / 146097;
    }
    function monthsToDays(months) {
        // the reverse of daysToMonths
        return (months * 146097) / 4800;
    }
    function as(units) {
        if (!this.isValid()) {
            return NaN;
        }
        var days,
            months,
            milliseconds = this._milliseconds;
        units = normalizeUnits(units);
        if (units === 'month' || units === 'quarter' || units === 'year') {
            days = this._days + milliseconds / 864e5;
            months = this._months + daysToMonths(days);
            switch (units) {
                case 'month':
                    return months;
                case 'quarter':
                    return months / 3;
                case 'year':
                    return months / 12;
            }
        } else {
            // handle milliseconds separately because of floating point math errors (issue #1867)
            days = this._days + Math.round(monthsToDays(this._months));
            switch (units) {
                case 'week':
                    return days / 7 + milliseconds / 6048e5;
                case 'day':
                    return days + milliseconds / 864e5;
                case 'hour':
                    return days * 24 + milliseconds / 36e5;
                case 'minute':
                    return days * 1440 + milliseconds / 6e4;
                case 'second':
                    return days * 86400 + milliseconds / 1000;
                // Math.floor prevents floating point math errors here
                case 'millisecond':
                    return Math.floor(days * 864e5) + milliseconds;
                default:
                    throw new Error('Unknown unit ' + units);
            }
        }
    }
    // TODO: Use this.as('ms')?
    function valueOf$1() {
        if (!this.isValid()) {
            return NaN;
        }
        return (
            this._milliseconds +
            this._days * 864e5 +
            (this._months % 12) * 2592e6 +
            toInt(this._months / 12) * 31536e6
        );
    }
    function makeAs(alias) {
        return function () {
            return this.as(alias);
        };
    }
    var asMilliseconds = makeAs('ms'),
        asSeconds = makeAs('s'),
        asMinutes = makeAs('m'),
        asHours = makeAs('h'),
        asDays = makeAs('d'),
        asWeeks = makeAs('w'),
        asMonths = makeAs('M'),
        asQuarters = makeAs('Q'),
        asYears = makeAs('y');
    function clone$1() {
        return createDuration(this);
    }
    function get$2(units) {
        units = normalizeUnits(units);
        return this.isValid() ? this[units + 's']() : NaN;
    }
    function makeGetter(name) {
        return function () {
            return this.isValid() ? this._data[name] : NaN;
        };
    }
    var milliseconds = makeGetter('milliseconds'),
        seconds = makeGetter('seconds'),
        minutes = makeGetter('minutes'),
        hours = makeGetter('hours'),
        days = makeGetter('days'),
        months = makeGetter('months'),
        years = makeGetter('years');
    function weeks() {
        return absFloor(this.days() / 7);
    }
    var round = Math.round,
        thresholds = {
            ss: 44, // a few seconds to seconds
            s: 45, // seconds to minute
            m: 45, // minutes to hour
            h: 22, // hours to day
            d: 26, // days to month/week
            w: null, // weeks to month
            M: 11, // months to year
        };
    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
    }
    function relativeTime$1(posNegDuration, withoutSuffix, thresholds, locale) {
        var duration = createDuration(posNegDuration).abs(),
            seconds = round(duration.as('s')),
            minutes = round(duration.as('m')),
            hours = round(duration.as('h')),
            days = round(duration.as('d')),
            months = round(duration.as('M')),
            weeks = round(duration.as('w')),
            years = round(duration.as('y')),
            a =
                (seconds <= thresholds.ss && ['s', seconds]) ||
                (seconds < thresholds.s && ['ss', seconds]) ||
                (minutes <= 1 && ['m']) ||
                (minutes < thresholds.m && ['mm', minutes]) ||
                (hours <= 1 && ['h']) ||
                (hours < thresholds.h && ['hh', hours]) ||
                (days <= 1 && ['d']) ||
                (days < thresholds.d && ['dd', days]);
        if (thresholds.w != null) {
            a =
                a ||
                (weeks <= 1 && ['w']) ||
                (weeks < thresholds.w && ['ww', weeks]);
        }
        a = a ||
            (months <= 1 && ['M']) ||
            (months < thresholds.M && ['MM', months]) ||
            (years <= 1 && ['y']) || ['yy', years];
        a[2] = withoutSuffix;
        a[3] = +posNegDuration > 0;
        a[4] = locale;
        return substituteTimeAgo.apply(null, a);
    }
    // This function allows you to set the rounding function for relative time strings
    function getSetRelativeTimeRounding(roundingFunction) {
        if (roundingFunction === undefined) {
            return round;
        }
        if (typeof roundingFunction === 'function') {
            round = roundingFunction;
            return true;
        }
        return false;
    }
    // This function allows you to set a threshold for relative time strings
    function getSetRelativeTimeThreshold(threshold, limit) {
        if (thresholds[threshold] === undefined) {
            return false;
        }
        if (limit === undefined) {
            return thresholds[threshold];
        }
        thresholds[threshold] = limit;
        if (threshold === 's') {
            thresholds.ss = limit - 1;
        }
        return true;
    }
    function humanize(argWithSuffix, argThresholds) {
        if (!this.isValid()) {
            return this.localeData().invalidDate();
        }
        var withSuffix = false,
            th = thresholds,
            locale,
            output;
        if (typeof argWithSuffix === 'object') {
            argThresholds = argWithSuffix;
            argWithSuffix = false;
        }
        if (typeof argWithSuffix === 'boolean') {
            withSuffix = argWithSuffix;
        }
        if (typeof argThresholds === 'object') {
            th = Object.assign({}, thresholds, argThresholds);
            if (argThresholds.s != null && argThresholds.ss == null) {
                th.ss = argThresholds.s - 1;
            }
        }
        locale = this.localeData();
        output = relativeTime$1(this, !withSuffix, th, locale);
        if (withSuffix) {
            output = locale.pastFuture(+this, output);
        }
        return locale.postformat(output);
    }
    var abs$1 = Math.abs;
    function sign(x) {
        return (x > 0) - (x < 0) || +x;
    }
    function toISOString$1() {
        // for ISO strings we do not use the normal bubbling rules:
        //  * milliseconds bubble up until they become hours
        //  * days do not bubble at all
        //  * months bubble up until they become years
        // This is because there is no context-free conversion between hours and days
        // (think of clock changes)
        // and also not between days and months (28-31 days per month)
        if (!this.isValid()) {
            return this.localeData().invalidDate();
        }
        var seconds = abs$1(this._milliseconds) / 1000,
            days = abs$1(this._days),
            months = abs$1(this._months),
            minutes,
            hours,
            years,
            s,
            total = this.asSeconds(),
            totalSign,
            ymSign,
            daysSign,
            hmsSign;
        if (!total) {
            // this is the same as C#'s (Noda) and python (isodate)...
            // but not other JS (goog.date)
            return 'P0D';
        }
        // 3600 seconds -> 60 minutes -> 1 hour
        minutes = absFloor(seconds / 60);
        hours = absFloor(minutes / 60);
        seconds %= 60;
        minutes %= 60;
        // 12 months -> 1 year
        years = absFloor(months / 12);
        months %= 12;
        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
        s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
        totalSign = total < 0 ? '-' : '';
        ymSign = sign(this._months) !== sign(total) ? '-' : '';
        daysSign = sign(this._days) !== sign(total) ? '-' : '';
        hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
        return (
            totalSign +
            'P' +
            (years ? ymSign + years + 'Y' : '') +
            (months ? ymSign + months + 'M' : '') +
            (days ? daysSign + days + 'D' : '') +
            (hours || minutes || seconds ? 'T' : '') +
            (hours ? hmsSign + hours + 'H' : '') +
            (minutes ? hmsSign + minutes + 'M' : '') +
            (seconds ? hmsSign + s + 'S' : '')
        );
    }
    var proto$2 = Duration.prototype;
    proto$2.isValid = isValid$1;
    proto$2.abs = abs;
    proto$2.add = add$1;
    proto$2.subtract = subtract$1;
    proto$2.as = as;
    proto$2.asMilliseconds = asMilliseconds;
    proto$2.asSeconds = asSeconds;
    proto$2.asMinutes = asMinutes;
    proto$2.asHours = asHours;
    proto$2.asDays = asDays;
    proto$2.asWeeks = asWeeks;
    proto$2.asMonths = asMonths;
    proto$2.asQuarters = asQuarters;
    proto$2.asYears = asYears;
    proto$2.valueOf = valueOf$1;
    proto$2._bubble = bubble;
    proto$2.clone = clone$1;
    proto$2.get = get$2;
    proto$2.milliseconds = milliseconds;
    proto$2.seconds = seconds;
    proto$2.minutes = minutes;
    proto$2.hours = hours;
    proto$2.days = days;
    proto$2.weeks = weeks;
    proto$2.months = months;
    proto$2.years = years;
    proto$2.humanize = humanize;
    proto$2.toISOString = toISOString$1;
    proto$2.toString = toISOString$1;
    proto$2.toJSON = toISOString$1;
    proto$2.locale = locale;
    proto$2.localeData = localeData;
    proto$2.toIsoString = deprecate(
        'toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)',
        toISOString$1
    );
    proto$2.lang = lang;
    // FORMATTING
    addFormatToken('X', 0, 0, 'unix');
    addFormatToken('x', 0, 0, 'valueOf');
    // PARSING
    addRegexToken('x', matchSigned);
    addRegexToken('X', matchTimestamp);
    addParseToken('X', function (input, array, config) {
        config._d = new Date(parseFloat(input) * 1000);
    });
    addParseToken('x', function (input, array, config) {
        config._d = new Date(toInt(input));
    });
    //! moment.js
    hooks.version = '2.29.4';
    setHookCallback(createLocal);
    hooks.fn = proto;
    hooks.min = min;
    hooks.max = max;
    hooks.now = now;
    hooks.utc = createUTC;
    hooks.unix = createUnix;
    hooks.months = listMonths;
    hooks.isDate = isDate;
    hooks.locale = getSetGlobalLocale;
    hooks.invalid = createInvalid;
    hooks.duration = createDuration;
    hooks.isMoment = isMoment;
    hooks.weekdays = listWeekdays;
    hooks.parseZone = createInZone;
    hooks.localeData = getLocale;
    hooks.isDuration = isDuration;
    hooks.monthsShort = listMonthsShort;
    hooks.weekdaysMin = listWeekdaysMin;
    hooks.defineLocale = defineLocale;
    hooks.updateLocale = updateLocale;
    hooks.locales = listLocales;
    hooks.weekdaysShort = listWeekdaysShort;
    hooks.normalizeUnits = normalizeUnits;
    hooks.relativeTimeRounding = getSetRelativeTimeRounding;
    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
    hooks.calendarFormat = getCalendarFormat;
    hooks.prototype = proto;
    // currently HTML5 input type only supports 24-hour formats
    hooks.HTML5_FMT = {
        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" />
        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" />
        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" />
        DATE: 'YYYY-MM-DD', // <input type="date" />
        TIME: 'HH:mm', // <input type="time" />
        TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" />
        TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" />
        WEEK: 'GGGG-[W]WW', // <input type="week" />
        MONTH: 'YYYY-MM', // <input type="month" />
    };
    return hooks;
})));;
/*! jQuery calendar 1.0.2 (c) github.com/teamdf/jquery-calendar | opensource.teamdf.com/license */
(function(f){var j="cal";var d="1.0.1";var g="month";var h="week";var e={startdate:null,daystodisplay:null,startmonth:null,startyear:null,monthstodisplay:null,defaultcolor:"#255BA1",invalidcolor:"#888888",maskmonthlabel:"l",maskeventlabel:"g:i A",maskdatelabel:"D, jS",masktimelabel:{"00":"g:i <\\sp\\a\\n>A</\\sp\\a\\n>",noon:"\\N\\O\\O\\N"},resources:false,minwidth:130,minheight:null,overlapoffset:15,daytimestart:"00:00:00",daytimeend:"24:00:00",weekstart:1,dragincrement:"15 mins",gridincrement:"15 mins",creationsize:"15 mins",allowcreation:"both",allowmove:false,allowresize:false,allowselect:false,allowremove:false,allowoverlap:false,allownotesedit:false,easing:{eventupdate:"linear",eventremove:"linear",eventeditin:"linear",eventeditout:"linear",datechange:"linear"},eventcreate:f.noop,eventnotesedit:f.noop,eventremove:f.noop,eventselect:f.noop,eventmove:f.noop,eventresize:f.noop,dayclick:f.noop,daydblclick:f.noop,onload:f.noop};var k={prevent:function(l){l.preventDefault()},scrollbarSize:function(){if(!k._scrollbarSize){var m=f(document.body),l=m.css({overflow:"hidden"}).width();l-=m.css({overflow:"scroll"}).width();if(!l){l=m.width()-m[0].clientWidth}m.css({overflow:""});k._scrollbarSize=l}return k._scrollbarSize},_scrollbarSize:false,selectrange:function(m,l){return this.each(function(){if(this.setSelectionRange){this.focus();this.setSelectionRange(m,l)}else{if(this.createTextRange){var n=this.createTextRange();n.collapse(true);n.moveEnd("character",l);n.moveStart("character",m);n.select()}}})},onscroll:function(p){var o=f(this),n=o.parent(".ui-"+j+"-container"),q=o.scrollLeft(),m=o.scrollTop(),l=n.data(j);if(l){n.find(".ui-"+j+"-timeline").scrollTop(m);n.find(".ui-"+j+"-dateline").scrollLeft(q);n.find(".ui-"+j+"-resourceline").scrollLeft(q)}},between:function(m,o,l){if(m instanceof Date){var n=m.getTime();return(n>=o.getTime()&&n<=l.getTime())}else{if(!isNaN(Number(m))){return(m>=o&&m<=l)}}return false},inrange:function(m,n,o,l){return !(n.getTime()<o.getTime()||m.getTime()>l.getTime())},resource:function(l,o){var n=0;if(o.settings.resources!==false){for(var m in o.settings.resources){if(o.settings.resources.hasOwnProperty(m)){if(n==l){return{id:m,name:o.settings.resources[m]}}n++}}}return{id:null,name:null}},resourceIndex:function(o,n){var l=0;if(n.settings.resources!==false){if(f.isArray(n.settings.resources)){for(var m in n.settings.resources){if(n.settings.resources[m]==o){return l}l++}}else{for(var m in n.settings.resources){if(n.settings.resources.hasOwnProperty(m)){if(m==o){return l}l++}}}}return false},overlaps:function(m,p,n){var t=f(this),r=t.data(j),l=[];if(r){var u=r.cache.events;for(var s in u){if(u.hasOwnProperty(s)&&(u[s].begins<p&&u[s].ends>m&&u[s].resource===n)){u[s].overlap={partial:true,inset:0,count:0,items:{},uid:s};l.push(u[s])}}if(l.length>1){l.sort(function(w,v){return w.begins.getTime()-v.begins.getTime()});for(var q in l){if(l.hasOwnProperty(q)){for(var o in l){if(q===o){continue}if(l.hasOwnProperty(o)&&!(l[q].overlap.uid in l[o].overlap.items)&&!(l[o].overlap.uid in l[q].overlap.items)&&(l[q].begins<l[o].ends&&l[q].ends>l[o].begins&&l[q].resource===l[o].resource)){l[q].overlap.items[l[o].overlap.uid]=l[o];l[o].overlap.items[l[q].overlap.uid]=l[q];l[q].overlap.count++;l[o].overlap.count++;if(l[q].begins.getTime()==l[o].begins.getTime()){l[q].overlap.partial=false;l[o].overlap.partial=false;l[o].overlap.inset=l[q].overlap.inset+1}else{if(l[q].begins.getTime()<l[o].begins.getTime()){if(l[q].overlap.partial){l[o].overlap.inset++}}else{if(l[o].overlap.partial){l[q].overlap.inset++}}}r.cache.events[l[q].overlap.uid]=l[q];r.cache.events[l[o].overlap.uid]=l[o]}}}}for(var s in l){l[s].elems.data(j,l[s])}}t.data(j,r)}},errors:{eventParse:function(n,m){var l=new Error(n);l.type="EventParse";l.event=m;return l},icsParse:function(n,l,o){var m=new Error(n);m.type="ICSParse";m.line=l;m.value=o;return m}},parse:{_icalendar:{folds:/^\s(.*)$/,entry:/^([A-Za-z0-9-]+)((?:;[A-Za-z0-9-]+=(?:"[^"]+"|[^";:,]+)(?:,(?:"[^"]+"|[^";:,]+))*)*):(.*)$/,param:/;([A-Za-z0-9-]+)=((?:"[^"]+"|[^";:,]+)(?:,(?:"[^"]+"|[^";:,]+))*)/g,value:/,?("[^"]+"|[^";:,]+)/g,date:/^(\d{4})(\d\d)(\d\d)$/,time:/^(\d{4})(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)(Z?)$/,range:/^(\d{4})(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)(Z?)\/(\d{4})(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)(Z?)$/,offset:/^([+-])(\d\d)(\d\d)$/,duration:/^([+-])?P(\d+W)?(\d+D)?(T)?(\d+H)?(\d+M)?(\d+S)?$/},icalendar:function(o){var n=k.errors.icsParse,m=k.parse._icalendar,s="cal_begin",t=[],u=o.replace(/\r\n/g,"\n").split("\n"),l=null,q=null;for(var p=u.length-1;p>0;p--){var r=m.folds.exec(u[p]);if(r){u[p-1]+=r[1];u[p]=""}}f.each(u,function(w,v){if(!v){return}switch(s){case"cal_begin":if(v.indexOf("BEGIN:VCALENDAR")==-1){throw new n("Expecting BEGIN:VCALENDAR but found '"+v+"' instead.",w,v)}q={events:[]};s="cal_info";break;case"cal_info":if(v.indexOf("BEGIN:VEVENT")==0){l={};s="cal_event"}if(v.indexOf("END:VCALENDAR")==0){t.push(q);s="done"}if(s!=="cal_info"){return}break;case"cal_event":if(v.indexOf("END:VEVENT")==0){q.events.push(l);s="cal_info"}if(s!=="cal_event"){return}var x=m.entry.exec(v);if(!x){throw new n("Missing entry name.",w,v)}switch(x[1].toLowerCase()){case"uid":l.uid=x[3];break;case"dtstart":l.begins=f[j].date(x[3]);break;case"dtend":l.ends=f[j].date(x[3]);break;case"summary":l.notes=x[3];break}break}});if(s!=="done"){throw new n("Unexpected end of file. Expecting END:VCALENDAR.",u.length,"")}return t.length>0?t.pop():false}},event:{calculateElementCount:function(l){return Math.ceil(l.cache.begins.getDaysBetween(l.cache.ends,true))+1},update:function(r,p,q){var m=f(this),l=m.data(j),o=l&&l.calendar?l.calendar.data(j):false;if(o&&l){var n=l.elems;if("begins" in r){l.begins=f[j].date(r.begins)}if("ends" in r){l.ends=f[j].date(r.ends)}if("color" in r){l.colors=r.color?f[j].colors.generate(r.color):o.settings.defaultcolor}if("title" in r){l.title=r.title||null}if("notes" in r){l.notes=r.notes||""}if(l.ends<o.settings.startdate||l.begins>o.cache.enddate){return false}l.cache.ends=(o.cache.enddate<l.ends?o.cache.enddate.addSeconds(-1):l.ends);l.cache.begins=(o.settings.startdate>l.begins?o.settings.startdate.copy():l.begins);n.find("pre.details").text(l.notes);n.find("p.title").text(l.title||l.begins.format(o.settings.maskeventlabel));n.data(j,l);o.cache.events[l.uid]=l;l.calendar.data(j,o);k.draw[o.type].position.apply(n,[p,q]);return true}return false},edit:function(r){var l=r&&!f(this).is("div.ui-"+j+"-event")?f(this).parents("div.ui-"+j+"-event"):f(this),t=l.data(j),o=t&&t.calendar?t.calendar.data(j):false;if(o&&t){if(!o.settings.allownotesedit){return}var q=l.find("pre.details"),n=q.height();var p=f('<textarea class="details" />').text(t.notes||"").css({boxShadow:"inset 0px 0px 6px "+t.colors.mainShadow}).on("mousedown."+j,function(u){u.stopPropagation()}).appendTo(l);if(l.height()<=30){var s=l.height()<=15?4:1,m=l.height()<=15?-1:0;l.unbind("dblclick."+j).stop(true,true);p.css({marginTop:m,left:s,right:s,height:n,border:"1px solid "+t.colors.mainSelected,borderTop:"none",borderTopLeftRadius:0,borderTopRightRadius:0,opacity:0,overflow:"hidden",zIndex:1}).animate({height:45,opacity:1},"fast",o.settings.easing.eventeditin,function(){f(this).css("overflow","scroll");q.detach();k.selectrange.apply(p,[t.notes.length||0,t.notes.length||0])})}else{q.detach();k.selectrange.apply(p,[t.notes.length||0,t.notes.length||0])}p.blur(function(){var u=t.notes!=f(this).val(),v=t.elems;t.notes=f(this).val();v.attr("title",t.notes||"");if(l.height()<=30){f(this).css("overflow","hidden");f(this).animate({height:n,opacity:0},125,o.settings.easing.eventeditout,function(){f(this).remove()})}else{f(this).remove()}v.append(q.text(t.notes||""));l.bind("dblclick."+j,k.event.edit);if(u){v.data(j,t);o.cache.events[t.uid]=t;t.calendar.data(j,o);o.settings.eventnotesedit.apply(t.calendar,[t.uid,t,v])}})}if(r){r.preventDefault();r.stopPropagation()}},select:function(m,n){var l=f(this),s=l.data(j),o=s&&s.calendar?s.calendar.data(j):false;if(o&&s){if(!o.settings.allowselect){return}if(m===undefined){m="fast"}var q=s.calendar.find("div.ui-"+j+"-event.selected"),r=q.data(j);if(r&&(r.uid===s.uid)){return}var t=o.settings.eventselect.apply(s.calendar,[s.uid,s,l]);if(t===undefined||t){var p=s.elems;q.removeClass("selected");p.addClass("selected");k.draw[o.type].position.apply(p,[m,n]);k.draw[o.type].position.apply(q,[m,n])}}},remove:function(u,m,o){var l=u?f(this).parent("div.ui-"+j+"-event"):f(this),y=l.data(j),p=y&&y.calendar?y.calendar.data(j):false;if(p&&y){if(m===undefined){m="fast"}if(!o){o=p.settings.easing.eventremove}var r=y.elems,z=p.settings.eventremove.apply(y.calendar,[y.uid,y,r,u]),w=function(){f(this).remove()};if(z===undefined||z){var n={width:0,height:0,fontSize:"0em",opacity:0.1};delete p.cache.events[y.uid];y.calendar.data(j,p);switch(r.length){case 1:n.left="+="+(l.width()/2);n.top="+="+(l.height()/2);l.animate(n,m,o,w);break;case 2:var s=r.eq(0),q=r.eq(1),v=f.extend({},n),t=f.extend({},n);v.left="+="+(r.eq(0).width());v.top=p.cache.dayHeight;t.top=0;s.delay(375).animate(v,m,o,w);q.animate(t,m,o,w);break;default:var x=0;r.each(function(){x+=f(this).width()});n.left=l.position().left+p.elements.container.scrollLeft()+(x/2);n.top=p.cache.dayHeight/2;r.first().delay(375).animate(n,m,o,w);r.filter(":not(:first)").animate(n,m,o,w);break}}}if(u){u.preventDefault();u.stopPropagation()}}},drag:{start:function(r){var l=f(this),o=r&&!l.is("div.ui-"+j+"-event")?l.parents("div.ui-"+j+"-event"):l,n=null,m=o.data(j),q=m&&m.calendar?m.calendar.data(j):false;if(q&&m){var p={event:o,data:q,values:m,i:"cal_"+(new Date()).getTime(),type:"resize"};k.drag[p.i]={started:false,startX:r.pageX,startY:r.pageY,lastX:r.pageX,lastY:r.pageY,deltaX:0,deltaY:0,incX:0,incY:0,obTime:m.begins.copy(),oeTime:m.ends.copy(),bTime:m.begins.roundToIncrement(q.settings.dragincrement),eTime:m.ends.roundToIncrement(q.settings.dragincrement),};o.stop(true,true);switch(true){case l.is(".ui-"+j+"-event"):p.lockBegins=Number(q.settings.startdate.format("Ymd"));p.lockEnds=Number(q.cache.enddate.format("Ymd"));p.lockDayBegins=Number(q.settings.daytimestart.replace(/[^0-9]/g,""));p.lockDayEnds=Number(q.settings.daytimeend.replace(/[^0-9]/g,""));p.type="move";f(document).bind("mousemove."+j,p,k.drag.move);break;case l.is(".resize-top"):p.lockDate=m.begins.format("Y-m-d");f(document).bind("mousemove."+j,p,k.drag.resizeB);break;case l.is(".resize-bottom"):p.lockDate=m.ends.format("Y-m-d");f(document).bind("mousemove."+j,p,k.drag.resizeE);break;default:delete k.drag[p.i];return true}f(document).bind("mouseup."+j,p,k.drag.end);r.stopPropagation()}},resizeB:function(r){var m=r.data.event,o=r.data.data,t=r.data.values,p=k.drag[r.data.i];p.deltaY=p.lastY-r.pageY;p.lastY=r.pageY;p.incY+=p.deltaY;if(p.deltaY==0){return true}if(!p.started&&(p.incY>5||p.incY<-5)){p.started=true;m.addClass("ui-dragging ui-resizing")}else{if(p.started){var l=Math.round(p.incY/o.cache.dragHeight);if(l===0){return true}var s=p.bTime.incrementBy(o.settings.dragincrement,0-l);var n=s.format("Y-m-d");var q=s.format("H:i:s");if(n===r.data.lockDate||q!==o.settings.daytimestart){if(n!==r.data.lockDate){s=f[j].date(r.data.lockDate+" "+o.settings.daytimestart);l=Math.round(s.getIncrementBetween(t.begins,o.settings.dragincrement))}if(s>=t.ends){l=Math.round(t.ends.getIncrementBetween(t.begins,o.settings.dragincrement));s=t.ends.incrementBy(o.settings.dragincrement,-1).copy();f(document).unbind("mousemove."+j).bind("mousemove."+j,r.data,k.drag.resizeE)}p.incY-=(l*o.cache.dragHeight);t.begins=p.bTime=s;t.cache.begins=(o.settings.startdate>t.begins?o.settings.startdate.copy():t.begins);m.data(j,t);o.cache.events[t.uid]=t;t.calendar.data(j,o);k.draw[o.type].position.apply(t.elems)}}}},resizeE:function(r){var m=r.data.event,o=r.data.data,t=r.data.values,p=k.drag[r.data.i];p.deltaY=p.lastY-r.pageY;p.lastY=r.pageY;p.incY+=p.deltaY;if(p.deltaY==0){return true}if(!p.started&&(p.incY>5||p.incY<-5)){p.started=true;m.addClass("ui-dragging ui-resizing")}else{if(p.started){var l=Math.round(p.incY/o.cache.dragHeight);if(l===0){return true}var s=p.eTime.incrementBy(o.settings.dragincrement,0-l);var n=s.format("Y-m-d");var q=s.format("H:i:s");if(n===r.data.lockDate||q!==o.settings.daytimeend){if(n!==r.data.lockDate){s=f[j].date(r.data.lockDate+" "+o.settings.daytimeend);l=Math.round(s.getIncrementBetween(t.ends,o.settings.dragincrement))}if(s<=t.begins){l=Math.round(t.begins.getIncrementBetween(t.ends,o.settings.dragincrement));s=t.begins.incrementBy(o.settings.dragincrement,1).copy();f(document).unbind("mousemove."+j).bind("mousemove."+j,r.data,k.drag.resizeB)}p.incY-=(l*o.cache.dragHeight);t.ends=p.eTime=s;t.cache.ends=(o.cache.enddate<s?o.cache.enddate.addSeconds(-1):s);m.data(j,t);o.cache.events[t.uid]=t;t.calendar.data(j,o);k.draw[o.type].position.apply(t.elems)}}}},move:function(r){var n=r.data.event,p=r.data.data,s=r.data.values,q=k.drag[r.data.i];q.deltaX=q.lastX-r.pageX;q.lastX=r.pageX;q.incX+=q.deltaX;q.deltaY=q.lastY-r.pageY;q.lastY=r.pageY;q.incY+=q.deltaY;if(!q.started&&(q.incY>5||q.incY<-5||q.incX>5||q.incY<-5)){q.started=true;n.addClass("ui-dragging")}else{if(q.started){switch(p.type){case h:var l=Math.round(q.incY/p.cache.dragHeight);var o=Math.round(q.incX/p.cache.dayWidth);if(l===0&&o===0){return true}var m=q.bTime.addDays(0-o).incrementBy(p.settings.dragincrement,0-l);var t=q.eTime.addDays(0-o).incrementBy(p.settings.dragincrement,0-l);q.incY-=(l*p.cache.dragHeight);q.incX-=(o*p.cache.dayWidth);s.begins=q.bTime=m;s.ends=q.eTime=t;s.cache.ends=(p.cache.enddate<t?p.cache.enddate.addSeconds(-1):t);s.cache.begins=(p.settings.startdate>s.begins?p.settings.startdate.copy():s.begins);n.data(j,s);p.cache.events[s.uid]=s;s.calendar.data(j,p);k.draw[p.type].position.apply(s.elems);break;case g:n.css({left:"-="+q.deltaX,top:"-="+q.deltaY});break}}}},end:function(o){var m=o.data.event,n=o.data.data,l=o.data.values;switch(o.data.type){case"resize":n.settings.eventresize.apply(l.calendar,[l.uid,l,m]);break;case"move":n.settings.eventmove.apply(l.calendar,[l.uid,l,m]);break}f(document).unbind("mousemove."+j).unbind("mouseup."+j);m.removeClass("ui-dragging ui-resizing");delete k.drag[o.data.i];k.draw[n.type].position.apply(l.elems)}},draw:{week:{cal:function(t){var A,z,B,v,s,u,y,n,q=f[j].date().format("Y-m-d");t.elements.timeblock.css({width:"100%",height:t.cache.incrementHeight});t.elements.timelabel.css({width:"100%",height:t.cache.incrementHeight});for(var p=0,x,m;p<t.cache.incrementsInDay;p++){B=t.settings.startdate.incrementBy(t.settings.gridincrement,p);m=B.format("H:i:s");x=B.format("i");A=t.elements.timeblock.clone(true);A.attr("time",m);A.attr("past",x);u=t.elements.timelabel.clone(true);u.attr("time",m);u.attr("past",x);if(m=="12:00:00"&&"noon" in t.settings.masktimelabel){u.find("p:first").html(B.format(t.settings.masktimelabel.noon))}else{if(x in t.settings.masktimelabel){u.find("p:first").html(B.format(t.settings.masktimelabel[x]))}}t.elements.dayblock.append(A);t.elements.timeline.append(u)}t.elements.dayblock.find("div.ui-"+j+"-time:first").css("border-top","0");t.elements.timeline.find("div.ui-"+j+"-label-time:first").html("");t.elements.dayblock.css({width:t.cache.resourceWidth,height:t.cache.dayHeight});t.elements.resourcelabel.css({width:t.cache.resourceWidth,height:"100%"});t.elements.datelabel.css({width:t.cache.dayWidth,height:"100%"});for(var p=0;p<t.settings.daystodisplay;p++){v=t.settings.startdate.addDays(p);n=v.format("Y-m-d");for(var l=0;l<t.cache.resourcecount;l++){z=t.elements.dayblock.clone(true).css("left",(t.cache.dayWidth*p)+(t.cache.resourceWidth*l)).attr({date:n,day:v.getDay(),resource:k.resource.apply(this,[l,t]).id});if(l<(t.cache.resourcecount-1)){z.addClass("ui-"+j+"-resource")}if(n===q){z.addClass("ui-"+j+"-today")}t.elements.container.append(z);if(t.settings.resources){s=t.elements.resourcelabel.clone(true).css("left",(t.cache.dayWidth*p)+(t.cache.resourceWidth*l)).attr({date:n,day:v.getDay(),resource:k.resource.apply(this,[l,t]).id}).find("p").html(k.resource.apply(this,[l,t]).name).end();t.elements.resourceline.append(s)}}y=t.elements.datelabel.clone(true).css("left",t.cache.dayWidth*p).attr({date:n,day:v.getDay(),}).find("p").html(v.format(t.settings.maskdatelabel)).end();if(n===q){y.addClass("ui-"+j+"-today")}t.elements.dateline.append(y)}t.elements.dateline.add(t.elements.resourceline).css({right:t.cache.scrollbarSize});var w=f(this);w.append(t.elements.timeline).append(t.elements.dateline).append(t.elements.datelinefill).append(t.elements.container);if(f.isArray(t.settings.resources)||typeof t.settings.resources=="object"){w.append(t.elements.resourceline).append(t.elements.resourcelinefill)}var o=(t.cache.dayHeight/2)-(t.elements.container.height()/2);t.elements.container.scrollTop(o)},event:function(p,m){m.cache.ends=(p.cache.enddate<m.ends?p.cache.enddate.addSeconds(-1):m.ends);m.cache.begins=(p.settings.startdate>m.begins?p.settings.startdate.copy():m.begins);var l=k.event.calculateElementCount.apply(this,[m]),n,o;if(!("elems" in m)||m.elems.length<1){n=i.event.clone(true);if(!p.settings.allowremove){n.find("span.button-remove").hide()}if(!p.settings.allowresize){n.find("p.resize-top, p.resize-bottom").hide()}if(p.settings.allowmove){n.find("pre.details").bind("selectstart."+j,k.prevent)}else{n.unbind("mousedown."+j,k.drag.start)}n.attr("data-id",m.uid);n.find("pre.details").text(m.notes);n.find("p.title").text(m.title||m.begins.format(p.settings.maskeventlabel));o=n}else{o=m.elems.detach();if(o.length>l){o.slice(0,l)}n=o.removeClass("begin end").addClass("mid").eq(0)}while(l>o.length){o=o.add(n.clone(true))}if(p.settings.startdate<=m.begins){o.first().removeClass("mid").addClass("begin")}if(p.cache.enddate>=m.ends){o.last().removeClass("mid").addClass("end")}p.elements.container.append(o);m.elems=o;o.data(j,m);k.draw[p.type].position.apply(o)},position:function(p,q,m){var o=f(this),l=o.data(j),n=l&&l.calendar?l.calendar.data(j):false,m=m===undefined?true:m;if(n&&l){o.each(function(v,s){var r=f(s),y=f[j].date(l.begins.addDays(v),n.settings.daytimestart),w=f[j].date(l.begins.addDays(v),n.settings.daytimeend);if(m){var t=l.overlap.items;k.overlaps.apply(l.calendar,[y,w,l.resource]);l=r.data(j);for(var x in l.overlap.items){k.draw[n.type].position.apply(l.overlap.items[x].elems,[false,false,false])}for(var x in t){if(!(x in l.overlap.items)){k.draw[n.type].position.apply(t[x].elems,[false,false,true])}}}var z={top:v>0?0:n.cache.incrementHeight*f[j].date(l.cache.begins,n.settings.daytimestart).getIncrementBetween(l.cache.begins,n.settings.gridincrement),left:n.cache.dayWidth*(n.settings.startdate.getDaysBetween(l.cache.begins,true)+v)+(n.cache.resourceWidth*l.resource),width:(l.resource!==null?n.cache.resourceWidth:n.cache.dayWidth)-1,height:Math.min(n.cache.dayHeight,n.cache.incrementHeight*(v<1?l.begins:y).getIncrementBetween((v==o.length-1?l.cache.ends:w),n.settings.gridincrement)),backgroundColor:r.hasClass("selected")?l.colors.mainSelected:l.colors.mainBackground,textShadow:l.colors.mainTextShadow+" 1px 1px 1px",color:l.colors.mainText};z.width-=n.settings.overlapoffset*l.overlap.count;z.left+=n.settings.overlapoffset*l.overlap.inset;var u={backgroundColor:l.colors.detailsBackground,textShadow:l.colors.detailsTextShadow+" 1px 1px 1px",color:l.colors.detailsText};if(z.height<=15){u.display="none";r.attr("title",l.notes||"").unbind("dblclick."+j).bind("dblclick."+j,k.event.edit)}else{u.display="block";r.removeAttr("title").unbind("dblclick."+j)}if(!l.title){r.find("p.title").text(l.begins.format(n.settings.maskeventlabel))}if(!p){r.css(z);r.find("pre.details").css(u)}else{r.stop(true,false).animate(z,p,q||n.settings.easing.eventupdate).find("pre.details").stop(true,false).animate(u,p,q||n.settings.easing.eventupdate).css("display",u.display);if(jQuery.ui===undefined){r.css({backgroundColor:z.backgroundColor,textShadow:z.textShadow,color:z.color});r.find("pre.details").css({backgroundColor:u.backgroundColor,textShadow:u.textShadow,color:u.color})}}})}}},month:{cal:function(m){var p,t,s,q,l,o=f[j].date().format("Y-m-d");m.elements.datelabel.css({width:m.cache.dayWidth,height:"100%"});m.elements.dayblock.css({width:m.cache.dayWidth,height:m.cache.dayHeight});for(var n=0;n<m.settings.daystodraw;n++){q=m.settings.startdate.addDays(n);l=q.format("Y-m-d");t=m.elements.dayblock.clone(true).attr({date:l,day:q.getDay()}).css({left:m.cache.dayWidth*(n%7),top:m.cache.dayHeight*Math.floor(n/7)}).toggleClass("non-month",q.getMonth()+1!=m.settings.startmonth).find("p").text(q.getDate()).end();if(l===o){t.addClass("ui-"+j+"-today")}if(n<7){s=m.elements.datelabel.clone(true).attr({date:l,day:q.getDay()}).css("left",m.cache.dayWidth*n).find("p").html(q.format(m.settings.maskmonthlabel)).end();m.elements.dateline.append(s)}m.elements.container.append(t)}var r=f(this);r.append(m.elements.dateline).append(m.elements.container)},event:function(p,m){m.cache.ends=(p.cache.enddate<m.ends?p.cache.enddate.addSeconds(-1):m.ends);m.cache.begins=(p.settings.startdate>m.begins?p.settings.startdate.copy():m.begins);var l=k.event.calculateElementCount.apply(this,[m]),n,o;if(!("elems" in m)||m.elems.length<1){n=i.event.clone(true);if(!p.settings.allowremove){n.find("span.button-remove").hide()}if(!p.settings.allowmove){n.unbind("mousedown."+j,k.drag.start)}n.find("p.resize-top, p.resize-bottom").hide();n.attr("data-id",m.uid);n.find("pre.details").text(m.notes);n.find("p.title").text("● "+(m.title||m.begins.format(p.settings.maskeventlabel)));n.attr("title",m.notes||"").unbind("dblclick."+j).bind("dblclick."+j,k.event.edit);o=n}else{o=m.elems.detach();if(o.length>l){o.slice(0,l)}n=o.removeClass("begin end").addClass("mid").eq(0)}while(l>o.length){o=o.add(n.clone(true))}if(p.settings.startdate<=m.begins){o.first().removeClass("mid").addClass("begin")}if(p.cache.enddate>=m.ends){o.last().removeClass("mid").addClass("end")}p.elements.container.append(o);m.elems=o;o.data(j,m);k.draw[p.type].position.apply(o)},position:function(p,q,m){var o=f(this),l=o.data(j),n=l&&l.calendar?l.calendar.data(j):false,m=m===undefined?true:m;if(n&&l){o.each(function(t,w){var s=f(w),v=s.hasClass("selected"),u=o.length>1;var r={top:n.cache.dayHeight*Math.floor((l.begins.addDays(t).getDate()-1)/7)+2+18,left:(n.cache.dayWidth*((l.begins.addDays(t).getDate()-1)%7))+(t>0?0:2),width:n.cache.dayWidth-(u&&t==0?2:4),height:n.cache.incrementHeight,backgroundColor:v?l.colors.mainSelected:"transparent",textShadow:v?l.colors.mainTextShadow+" 1px 1px 1px":"none",color:v?l.colors.mainText:l.colors.mainBackground};s.attr("title",l.notes||"");if(v){if(w.style.removeAttribute){w.style.removeAttribute("background-image")}else{w.style.removeProperty("background-image")}s.find("span.button-remove").show();if(u&&t==0){s.find("span.button-remove").hide()}if(t>0){s.find("p.title").hide()}}else{w.style.backgroundImage="none";s.find("span.button-remove").hide();if(t>0){s.find("p.title").show()}}if(!p){s.css(r).find("pre.details").hide()}else{s.stop(true,false).animate(r,p,q||n.settings.easing.eventupdate).find("pre.details").hide();if(jQuery.ui===undefined){s.css({backgroundColor:r.backgroundColor,textShadow:r.textShadow,color:r.color})}}})}}}}};var i={event:f(['<div class="ui-'+j+'-event mid">','<p class="resize-top" />','<p class="title" />','<span class="button-remove" />','<pre class="details" />','<p class="footer" />','<p class="resize-bottom" />',"</div>"].join("")).bind("selectstart."+j,k.prevent).bind("mousedown."+j,k.event.select).bind("mousedown."+j,k.drag.start).find("p.resize-top, p.resize-bottom").bind("mousedown."+j,k.drag.start).end().find("pre.details").bind("dblclick."+j,k.event.edit).end().find("p").bind("selectstart."+j,k.prevent).end().find("span.button-remove").bind("click."+j,k.event.remove).end(),day:f('<div class="ui-'+j+'-date" date="" day="" />').bind("selectstart."+j,k.prevent),time:f('<div class="ui-'+j+'-time" time="" past="" />'),labels:{time:f('<div class="ui-'+j+'-label-time" time="" past="" ><p /></div>'),date:f('<div class="ui-'+j+'-label-date" date=""><p /><div class="delimiter" /></div>'),resource:f('<div class="ui-'+j+'-label-resource" date=""><p /><div class="delimiter" /></div>'),},timeline:f('<div class="ui-'+j+'-timeline" />').bind("selectstart."+j,k.prevent),dateline:f('<div class="ui-'+j+'-dateline" />').bind("selectstart."+j,k.prevent),datelinefill:f('<div class="ui-'+j+'-dateline-fill" />'),resourceline:f('<div class="ui-'+j+'-resourceline" />'),resourcelinefill:f('<div class="ui-'+j+'-resourceline-fill" />'),container:f('<div class="ui-'+j+'-wrapper" />').bind("scroll."+j,k.onscroll)};var c={init:function(l){return f(this).each(function(){var n=f.extend({},e);if(l){f.extend(n,l)}var s=f(this),o=s.data(j);if(!o){o={type:h,target:s,settings:n,elements:{},cache:{scrollbarSize:k.scrollbarSize(),enddate:undefined,incrementsInDay:undefined,incrementHeight:undefined,dragHeight:undefined,dayWidth:undefined,dayHeight:undefined,events:{},calendars:{}}};if(o.settings.startmonth===null&&o.settings.startyear===null&&o.settings.monthstodisplay===null){if(o.settings.startdate===null){o.settings.startdate=new Date()}if(o.settings.daystodisplay===null){o.settings.daystodisplay=7}}else{if(o.settings.startmonth===null){o.settings.startmonth=(new Date()).getMonth()+1}if(o.settings.startyear===null){o.settings.startyear=(new Date()).getFullYear()}if(o.settings.monthstodisplay===null){o.settings.monthstodisplay=1}o.settings.startdate=f[j].date(o.settings.startyear+"-"+(Number(o.settings.startmonth)<10?"0":"")+Number(o.settings.startmonth)+"-01");o.cache.enddate=o.settings.startdate.addMonths(o.settings.monthstodisplay);o.settings.daystodisplay=o.settings.startdate.getDaysBetween(o.cache.enddate);o.type=g}o.settings.startdate=f[j].date(o.settings.startdate,o.settings.daytimestart);o.settings.defaultcolor=f[j].colors.generate(o.settings.defaultcolor);o.settings.invalidcolor=f[j].colors.generate(o.settings.invalidcolor);o.settings.minheight=Math.round(o.settings.minheight===null?f[j].incrementsIn(o.settings.gridincrement,"1 min"):o.settings.minheight);o.cache.enddate=o.settings.startdate.addDays(o.settings.daystodisplay);o.cache.incrementsInDay=o.settings.startdate.getIncrementBetween(f[j].date(o.settings.startdate,o.settings.daytimeend),o.settings.gridincrement);o.cache.incrementHeight=o.settings.minheight;o.cache.dragHeight=(o.cache.incrementHeight/f[j].incrementsIn(o.settings.gridincrement,o.settings.dragincrement));o.cache.resourcecount=1;s.addClass("ui-"+j+" ui-"+j+"-container ui-"+j+"-"+o.type);o.elements.dateline=i.dateline.clone(true);o.elements.container=i.container.clone(true);o.elements.dayblock=i.day.clone(true);o.elements.datelabel=i.labels.date.clone(true);o.elements.resourcelabel=i.labels.resource.clone(true);switch(o.type){case g:var p=o.settings.startdate.getDay();var m=o.cache.enddate.addDays(1).getDay();var r=o.settings.weekstart-1;var u=r==0?6:r-1;o.settings.startdate=o.settings.startdate.addDays((r>p?r-7:r)-p);o.cache.enddate=o.cache.enddate.addDays(u-m+2);o.settings.daystodraw=o.settings.startdate.getDaysBetween(o.cache.enddate);o.cache.weekstodraw=o.settings.startdate.getWeeksBetween(o.cache.enddate);o.elements.dayblock.append("<p/>");o.cache.monthWidth=s.outerWidth()/o.settings.monthstodisplay;o.cache.dayWidth=o.cache.monthWidth/7;o.cache.dayHeight=(s.outerHeight()-22)/o.cache.weekstodraw;k.draw.month.cal.apply(this,[o]);break;case h:if(f.isArray(o.settings.resources)||typeof o.settings.resources=="object"){o.cache.resourcecount=0;for(var q in o.settings.resources){if(o.settings.resources.hasOwnProperty(q)){o.cache.resourcecount++}}s.addClass("ui-"+j+"-resources");o.elements.resourceline=i.resourceline.clone(true);o.elements.resourcelinefill=i.resourcelinefill.clone(true)}o.elements.datelinefill=i.datelinefill.clone(true);o.elements.timeline=i.timeline.clone(true);o.elements.timeblock=i.time.clone(true);o.elements.timelabel=i.labels.time.clone(true);var t=(s.outerWidth()-60)/(o.settings.daystodisplay*o.cache.resourcecount);o.cache.resourceWidth=Math.max(o.settings.minwidth,t);o.cache.dayWidth=o.cache.resourceWidth*o.cache.resourcecount;o.cache.dayHeight=o.cache.incrementHeight*o.cache.incrementsInDay;k.draw.week.cal.apply(this,[o]);break}s.data(j,o);if(!f.isArray(o.settings.calendars)){o.settings.calendars=[o.settings.events]}f(o.settings.calendars).each(function(){var x,v;if(f.isArray(this)){x=this}else{if(typeof this=="string"){x=this}else{if(f.isPlainObject(this)){x=this.events;v=this.color}}}if(f.isArray(x)){for(var w=0;w<x.length;w++){if(!("color" in x[w])){x[w].color=v}c.add.apply(s,[x[w]])}}else{if(typeof x=="string"){f.ajax(x,{accepts:"text/calendar",dataType:"text",type:"get",crossDomain:true,data:{from:o.settings.datefrom,to:o.settings.dateto},success:function(y){var B=k.parse.icalendar.apply(s,[y]);if(B&&"events" in B&&f.isArray(B.events)&&B.events.length>0){for(var z=0,A;z<B.events.length;z++){if(!("color" in B.events[z])){B.events[z].color=v}c.add.apply(s,[B.events[z]])}}}})}}});o.settings.calendars=undefined;o.settings.events=undefined;o.settings.onload.apply(s)}})},add:function(q){var o=f(this),m=o.data(j);if(m){if(!"uid" in q){throw k.errors.eventParse("Missing unique id (uid)",q)}if(!"begins" in q){throw k.errors.eventParse("Missing start date/time (begins)",q)}if(!"ends" in q){throw k.errors.eventParse("Missing end date/time (ends)",q)}if(q.uid in m.cache.events){throw k.errors.eventParse("UID must be unique",q)}var n=f[j].date(q.begins),p=f[j].date(q.ends);var l={elems:f([]),calendar:o,uid:q.uid,begins:n,ends:p,resource:m.settings.resources&&q.resource?k.resourceIndex.apply(this,[q.resource,m]):null,colors:q.color?f[j].colors.generate(q.color):m.settings.defaultcolor,title:q.title||null,notes:q.notes||"",cache:{},overlap:{inset:[],depth:[]}};if(l.resource===false){throw k.errors.eventParse("Invalid resource id (resource)",q)}if(!(l.begins instanceof Date)){throw k.errors.eventParse("Invalid start date/time (begins)",q)}m.cache.events[l.uid]=l;o.data(j,m);if(k.inrange.apply(this,[n,p,m.settings.startdate,m.cache.enddate])){k.draw[m.type].event.apply(o,[m,l])}}return o},update:function(l,p,r){var q=f(this),m,o=q.data(j);if(o){if(p===undefined){p="fast"}if(f.isArray(l)){for(var n=0;n<l.length;n++){m=o.elements.container.find("div.ui-"+j+'-event[data-id="'+l[n].uid+'"]');if(m.length>0){k.event.update.apply(m,[l[n],p,r])}}}else{m=o.elements.container.find("div.ui-"+j+'-event[data-id="'+l.uid+'"]');if(m.length>0){k.event.update.apply(m,[l,p,r])}}}return q},select:function(l,n,p){var o=f(this),m=o.data(j);if(m){$event=m.elements.container.find("div.ui-"+j+'-event[data-id="'+l+'"]');if($event.length>0){k.event.select.apply($event,[n,p])}}return o},option:function(u,t){var s=f(this),q=s.data(j);if(q){if(typeof u=="undefined"){return q.settings}if(typeof u=="object"){for(var n in u){if(u.hasOwnProperty(n)){c.option.apply(s,[n,u[n]])}}return s}if(!u in q.settings){return false}if(typeof t=="undefined"){return q.settings[u]}else{switch(u){case"allowremove":q.elements.container.find("div.ui-"+j+"-event span.button-remove").toggle(Boolean(t));break;case"allowresize":q.elements.container.find("p.resize-top, p.resize-bottom").toggle(Boolean(t));break;case"startdate":var r=f[j].date(t,q.settings.daytimestart),v=q.settings.startdate;q.settings.startdate=r;q.cache.enddate=r.addDays(q.settings.daystodisplay);s.data(j,q);var m;for(var p in q.cache.events){m=q.cache.events[p];if(!k.inrange.apply(this,[m.begins,m.ends,q.settings.startdate,q.cache.enddate])){if("elems" in m&&m.elems.length>0){m.elems.detach()}}else{k.draw[q.type].event.apply(s,[q,m])}}var l=f("div.ui-"+j+"-date",q.elements.container).removeClass("ui-"+j+"-today"),o=f[j].date().format("Y-m-d");switch(q.type){case g:f(q.elements.dayblock).removeClass("ui-"+j+"-today").each(function(y,x){var A=f(x),w=r.addDays(y),z=w.format("Y-m-d");A.attr({date:z,day:w.getDay()}).find("p").html(w.format("j")).end();if(z===o){A.addClass("ui-"+j+"-today")}});break;case h:f("div.ui-"+j+"-label-date",q.elements.dateline).removeClass("ui-"+j+"-today").each(function(z,y){var w=f(y),x=r.addDays(z),A=x.format("Y-m-d");l.eq(z).attr({date:A,day:x.getDay()});w.attr({date:A,day:x.getDay()}).find("p").html(x.format(q.settings.maskdatelabel)).end();if(A===o){w.add(l.eq(z)).addClass("ui-"+j+"-today")}});break}return s;break;default:q.settings[u]=t;break}return s}}},version:function(){return j+" v"+d},destroy:function(){return this.each(function(){var n=f(this),m=n.data(j);if(m){for(var l=0;l<m.cache.events.length;l++){m.cache.events[l].elems.remove()}n.removeData(j);n.empty()}})}};f.fn[j]=function(l){if(c[l]){return c[l].apply(this,Array.prototype.slice.call(arguments,1))}else{if(typeof l==="object"||!l){return c.init.apply(this,arguments)}else{f.error("Method "+l+" does not exist on jQuery."+j)}}};f[j]={};f[j].colors={named:{aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aqua:"#00FFFF",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blue:"#0000FF",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",fuchsia:"#FF00FF",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",gray:"#808080",green:"#008000",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgrey:"#D3D3D3",lightgreen:"#90EE90",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",lime:"#00FF00",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",maroon:"#800000",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370D8",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",navy:"#000080",oldlace:"#FDF5E6",olive:"#808000",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#D87093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",purple:"#800080",reactorblue:"#0266A1",red:"#FF0000",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",silver:"#C0C0C0",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",teal:"#008080",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",white:"#FFFFFF",whitesmoke:"#F5F5F5",yellow:"#FFFF00",yellowgreen:"#9ACD32"},HexToRGB:function(m,l){return(l!==undefined?"rgba":"rgb")+"("+f[j].colors.HexToR(m)+", "+f[j].colors.HexToG(m)+", "+f[j].colors.HexToB(m)+(l!==undefined?", "+l+")":")")},HexToR:function(l){return parseInt((f[j].colors.cutHex(l)).substring(0,2),16)},HexToG:function(l){return parseInt((f[j].colors.cutHex(l)).substring(2,4),16)},HexToB:function(l){return parseInt((f[j].colors.cutHex(l)).substring(4,6),16)},cutHex:function(l){return(l.charAt(0)=="#")?f[j].colors.padHex(l.substring(1,7)):f[j].colors.padHex(l)},padHex:function(l){return l.length>3?l:l.substring(0,1)+l.substring(0,1)+l.substring(1,2)+l.substring(1,2)+l.substring(2,3)+l.substring(2,3)},HueToRGB:function(n,m,l){if(l<0){l+=1}if(l>1){l-=1}if(l<1/6){return n+(m-n)*6*l}if(l<1/2){return m}if(l<2/3){return n+(m-n)*(2/3-l)*6}return n},HSLToRGB:function(u,A,t,z,w){var m,v,y;u/=360;A/=100;t/=100;if(A==0){m=v=y=t}else{var n=t<0.5?t*(1+A):t+A-t*A;var o=2*t-n;m=f[j].colors.HueToRGB(o,n,u+1/3);v=f[j].colors.HueToRGB(o,n,u);y=f[j].colors.HueToRGB(o,n,u-1/3)}var x=[Math.round(m*255),Math.round(v*255),Math.round(y*255)];if(w){if(z!==undefined){x[3]=z}return x}return(z!==undefined?"rgba":"rgb")+"("+x.join(", ")+(z!==undefined?", "+z+")":")")},RGBToHSL:function(m,q,u){m/=255,q/=255,u/=255;var v=Math.max(m,q,u),o=Math.min(m,q,u);var p,w,n=(v+o)/2;if(v==o){p=w=0}else{var t=v-o;w=n>0.5?t/(2-v-o):t/(v+o);switch(v){case m:p=(q-u)/t+(q<u?6:0);break;case q:p=(u-m)/t+2;break;case u:p=(m-q)/t+4;break}p/=6}return[Math.round(p*360),Math.round(w*100),Math.round(n*100)]},brightness:function(n,m,l){return((n*299)+(m*587)+(l*114))/1000},generate:function(m){var l=10;if(m in f[j].colors.named){m=f[j].colors.named[m]}if(m.match(/^#?([0-9A-Fa-f]{3,6})$/)){var q=[f[j].colors.HexToR(m),f[j].colors.HexToG(m),f[j].colors.HexToB(m)];var s=f[j].colors.RGBToHSL(q[0],q[1],q[2])}else{if(m.replace(/ /g,"").match(/([rR][gG][bB]\s*\(\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*\))|([rR][gG][bB]\(\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*\))/)){var q=m.replace(/[a-zA-Z\(\) ]/g,"").split(",");var s=f[j].colors.RGBToHSL(q[0],q[1],q[2])}else{if(m.replace(/ /g,"").match(/([hH][sS][lL]\s*\(\s*([0-9]|[1-9][0-9]|[1-2][0-9][0-9]|3[0-5][0-9]|360)\s*,\s*(\d?\d%|100%)\s*,\s*(\d?\d%|100%)\s*\))/)){var s=m.replace(/[a-zA-Z\(\) %]/g,"").split(",")}else{throw new Error("Invalid Colour: could not parse "+m+" as a color.")}}}if(s[1]<l){s[1]+=l}if(s[1]>100-l){s[1]-=l}if(s[2]>100-l){s[2]-=l}if(s[2]<l){s[2]+=l}function n(x,w,u){var v=f.extend([],x);v[1]=Math.max(0,v[1]+(w/2));v[2]=Math.min(100,v[2]+w);if(u!==undefined){v[3]=u}return v}function t(x,w,u){var v=f.extend([],x);v[2]=Math.max(0,v[2]-w);if(u!==undefined){v[3]=u}return v}var o=f[j].colors.HSLToRGB.apply(this,n(s,l*5,0.3));var p=f[j].colors.HSLToRGB.apply(this,n(s,l*3,0.75));var r=(f[j].colors.brightness.apply(this,f[j].colors.HSLToRGB(s[0],s[1],s[2],undefined,true))>125?"#333333":"#FFFFFF");return{original:m,mainBackground:f[j].colors.HSLToRGB.apply(this,s),mainTextShadow:o,mainShadow:p,mainText:r,mainSelected:f[j].colors.HSLToRGB.apply(this,t(s,l)),detailsBackground:f[j].colors.HSLToRGB.apply(this,n(s,l)),detailsTextShadow:o,detailsShadow:p,detailsText:r}}};f[j].lang={en:{short_month:Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"),long_month:Array("January","February","March","April","May","June","July","August","September","October","November","December"),short_day:Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat"),long_day:Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"),label_remove:"Remove",label_today:"Today"}};var a={d:function(){return(this.getDate()<10?"0":"")+this.getDate()},D:function(){return f[j].lang[this.lang].short_day[this.getDay()]},j:function(){return this.getDate()},l:function(){return f[j].lang[this.lang].long_day[this.getDay()]},N:function(){return this.getDay()+1},S:function(){return(this.getDate()%10==1&&this.getDate()!=11?"st":(this.getDate()%10==2&&this.getDate()!=12?"nd":(this.getDate()%10==3&&this.getDate()!=13?"rd":"th")))},w:function(){return this.getDay()},z:function(){if(window.console){console.error("Mask 'z' Not Yet Supported")}return"z"},W:function(){var l=new Date(this.getFullYear(),0,1);return Math.ceil((((this-l)/86400000)+l.getDay()+1)/7)},F:function(){return f[j].lang[this.lang].long_month[this.getMonth()]},m:function(){return(this.getMonth()+1<10?"0":"")+(this.getMonth()+1)},M:function(){return f[j].lang[this.lang].short_month[this.getMonth()]},n:function(){return this.getMonth()+1},t:function(){return(new Date((new Date(this.getFullYear(),this.getMonth()+1,1))-1)).getDate()},L:function(){if(window.console){console.error("Mask 'L' Not Yet Supported")}return"L"},o:function(){if(window.console){console.error("Mask 'o' Not Yet Supported")}return"o"},Y:function(){return this.getFullYear()},y:function(){return(""+this.getFullYear()).substr(2)},a:function(){return this.getHours()<12?"am":"pm"},A:function(){return this.getHours()<12?"AM":"PM"},B:function(){if(window.console){console.error("Mask 'B' Not Yet Supported")}return"B"},g:function(){return this.getHours()==0?12:(this.getHours()>12?this.getHours()-12:this.getHours())},G:function(){return this.getHours()},h:function(){return(this.getHours()<10||(12<this.getHours()<22)?"0":"")+(this.getHours()<10?this.getHours()+1:this.getHours()-12)},H:function(){return(this.getHours()<10?"0":"")+this.getHours()},i:function(){return(this.getMinutes()<10?"0":"")+this.getMinutes()},s:function(){return(this.getSeconds()<10?"0":"")+this.getSeconds()},e:function(){if(window.console){console.error("Mask 'e' Not Supported")}return"e"},I:function(){if(window.console){console.error("Mask 'I' Not Supported")}return"I"},O:function(){return this.toString().match(/GMT([+-][0-9]+) \(([a-zA-Z]+)\)/)[1]},P:function(){var l=this.toString().match(/GMT([+-][0-9]+) \(([a-zA-Z]+)\)/)[1].split("");l.splice(-2,0,":");return l.join("")},T:function(){return this.toString().match(/GMT([+-][0-9]+) \(([a-zA-Z]+)\)/)[2]},Z:function(){return this.getTimezoneOffset()*60},c:function(){return a.Y.apply(this)+"-"+a.m.apply(this)+"-"+a.d.apply(this)+"T"+a.H.apply(this)+":"+a.i.apply(this)+":"+a.s.apply(this)+a.P.apply(this)},C:function(){return a.c.apply(this).replace(a.P.apply(this),"")+"Z"},r:function(){return this.toString()},U:function(){return this.getTime()/1000}};var b={d:function(){return(this.getUTCDate()<10?"0":"")+this.getUTCDate()},D:function(){return f[j].lang[this.lang].short_day[this.getUTCDay()]},j:function(){return this.getUTCDate()},l:function(){return f[j].lang[this.lang].long_day[this.getUTCDay()]},N:function(){return this.getUTCDay()+1},S:function(){return(this.getUTCDate()%10==1&&this.getUTCDate()!=11?"st":(this.getUTCDate()%10==2&&this.getUTCDate()!=12?"nd":(this.getUTCDate()%10==3&&this.getUTCDate()!=13?"rd":"th")))},w:function(){return this.getUTCDay()},z:a.z,W:function(){var l=new Date(this.getUTCFullYear(),0,1);return Math.ceil((((this-l)/86400000)+l.getUTCDay()+1)/7)},F:function(){return f[j].lang[this.lang].long_month[this.getUTCMonth()]},m:function(){return(this.getUTCMonth()+1<10?"0":"")+(this.getUTCMonth()+1)},M:function(){return f[j].lang[this.lang].short_month[this.getUTCMonth()]},n:function(){return this.getUTCMonth()+1},t:function(){return(new Date((new Date(this.getUTCFullYear(),this.getUTCMonth()+1,1))-1)).getUTCDate()},L:a.L,o:a.o,Y:function(){return this.getUTCFullYear()},y:function(){return(""+this.getUTCFullYear()).substr(2)},a:function(){return this.getUTCHours()<12?"am":"pm"},A:function(){return this.getUTCHours()<12?"AM":"PM"},B:a.B,g:function(){return this.getUTCHours()==0?12:(this.getUTCHours()>12?this.getUTCHours()-12:this.getUTCHours())},G:function(){return this.getUTCHours()},h:function(){return(this.getUTCHours()<10||(12<this.getUTCHours()<22)?"0":"")+(this.getUTCHours()<10?this.getUTCHours()+1:this.getUTCHours()-12)},H:function(){return(this.getUTCHours()<10?"0":"")+this.getUTCHours()},i:function(){return(this.getUTCMinutes()<10?"0":"")+this.getUTCMinutes()},s:function(){return(this.getUTCSeconds()<10?"0":"")+this.getUTCSeconds()},e:a.e,I:a.I,O:a.O,P:a.P,T:a.T,Z:a.Z,c:function(){return b.Y.apply(this)+"-"+b.m.apply(this)+"-"+b.d.apply(this)+"T"+b.H.apply(this)+":"+b.i.apply(this)+":"+b.s.apply(this)+b.P.apply(this)},C:function(){return b.c.apply(this).replace(b.P.apply(this),"")+"Z"},r:a.r,U:function(){return this.getUTCTime()/1000}};f[j].format=function(m,r,p){var q="",l="";var o=p?b:a;for(var n=0;n<r.length;n++){l=r.charAt(n);if(l=="\\"&&o[r.charAt(n+1)]){q+=r.charAt(n+1);n++}else{if(a[l]){q+=o[l].call(m)}else{q+=l}}}return q};f[j].date=function(r,p,l){var t;var v;if(r instanceof Date){t=new Date(Date.UTC(r.getUTCFullYear(),r.getUTCMonth(),r.getUTCDate(),r.getUTCHours(),r.getUTCMinutes(),r.getUTCSeconds(),0));if(p!==undefined){var u=p.match(/[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}([Zz])?/)?true:p==""?true:false;if(u){var q,o,z;q=o=D=0;p=p.split(":");q=p[0];o=p[1];D=p[2];if((p[3]||"").toLowerCase()=="z"){t.setUTCHours(q);t.setUTCMinutes(o);t.setUTCSeconds(D)}else{t.setHours(q);t.setMinutes(o);t.setSeconds(D)}}}if("lang" in t){return t}}else{if(typeof r=="string"||(r&&typeof r=="object"&&"toString" in r)){if(r.toString()!==""){var x=r.toString().split(/[Tt ]/);if(p!==undefined){x[1]=!p?"":p}var C=0 in x?(x[0]==""?null:x[0].match(/([0-9]{2,4})-?([0-9]{2})-?([0-9]{2})/)):null;var B=1 in x?(x[1]==""?null:x[1].match(/([0-9]{2}):?([0-9]{2}):?([0-9]{2})([Zz])?/)):null;if(C===null){var w=new Date();C=["",w.getFullYear(),w.getMonth()+1,w.getDate()]}if(B===null){B=["",0,0,0]}if(C&&B){var A=C[1],n=C[2]-1,z=C[3],q=B[1],o=B[2],D=B[3];if((B[4]||"").toLowerCase()=="z"){t=new Date(Date.UTC(A,n,z,q,o,D,0))}else{t=new Date(A,n,z,q,o,D)}}}}}if(!(t instanceof Date)||isNaN(t)){t=new Date()}t.lang=l||"en";t.roundToDay=function(){return f[j].date(new Date(this.getUTCFullYear(),this.getUTCMonth(),this.getUTCDate(),0,0,0))};t.roundToMonth=function(){return f[j].date(new Date(this.getUTCFullYear(),this.getUTCMonth(),1,0,0,0))};t.getUTCTime=function(){return this.getTime()+(this.getTimezoneOffset()*60000)};t.getYearsBetween=function(y,s){var m=this.getMonthsBetween(y);return Math.floor(m/12)};t.getMonthsBetween=function(I,m){var G=this.copy(),F=I.copy();var E=G.copy();E.setDate(1);E.setMonth(E.getMonth()+1);E.setDate(0);E=E.getDate();var s=F.copy();s.setDate(1);s.setMonth(s.getMonth()+1);s.setDate(0);s=s.getDate();if(m){G.setDate(1);F.setDate(1)}var H=G.getFullYear()*12+G.getMonth();var y=F.getFullYear()*12+F.getMonth();if(!m){H+=(((G.getDate()+(G.getHours()/24)+(G.getMinutes()/24/60)-1)/E));y+=(((F.getDate()+(F.getHours()/24)+(G.getMinutes()/24/60)-1)/s))}return y-H};t.getWeeksBetween=function(F,s){var E=this.copy();var y=F.copy();if(s){E=E.addDays(1-E.getDay());E.setHours(0,0,0,0)}var m=E.getDaysBetween(y)/7;return(s?Math.floor(m):m)};t.getDaysBetween=function(F,m){var y=F.copy();if(m){y.setHours(this.getHours(),this.getMinutes(),this.getSeconds(),this.getMilliseconds())}var s=((-this.getTimezoneOffset()/60)-(-y.getTimezoneOffset()/60))*3600000;var E=y.getTime()-this.getTime();return(E-s)/86400000};t.getHoursBetween=function(F,m){var y=F.copy();if(m){y.setMinutes(this.getMinutes(),this.getSeconds(),this.getMilliseconds())}var s=((-this.getTimezoneOffset()/60)-(-y.getTimezoneOffset()/60))*3600000;var E=y.getTime()-this.getTime();return(E-s)/3600000};t.getMinutesBetween=function(F,m){var y=F.copy();if(m){y.setSeconds(this.getSeconds(),this.getMilliseconds())}var s=((-this.getTimezoneOffset()/60)-(-y.getTimezoneOffset()/60))*3600000;var E=y.getTime()-this.getTime();return(E-s)/60000};t.getSecondsBetween=function(s,m){return m?Math.round(this.getMinutesBetween(s)*60):this.getMinutesBetween(s)*60};t.addYears=function(G){var F=Math.floor(G);var s=Math.floor((G-F)*12);var E=this.copy();E.setFullYear(this.getFullYear()+F);E.setMonth(this.getMonth()+s);return E};t.addMonths=function(E){var s=Math.floor(E);var y=this.copy();y.setMonth(this.getMonth()+s);return y};t.addDays=function(H){var G=Math.floor(H);var F=Math.floor((H-G)*24);var y=Math.floor(((H-G)-(F/24))*24*60);var E=Math.floor(((H-G)-(F/24)-(y/24/60))*24*60*60);var m=this.copy();m.setDate(this.getDate()+G);m.setHours(this.getHours()+F);m.setMinutes(this.getMinutes()+y);m.setSeconds(this.getSeconds()+E);return m};t.addHours=function(G){var F=Math.floor(G);var y=Math.floor((G-F)*60);var E=Math.floor(((G-F)-(y/60))*60*60);var m=this.copy();m.setHours(this.getHours()+F);m.setMinutes(this.getMinutes()+y);m.setSeconds(this.getSeconds()+E);return m};t.addMinutes=function(F){var y=Math.floor(F);var E=Math.floor((F-y)*60);var m=this.copy();m.setMinutes(this.getMinutes()+y);m.setSeconds(this.getSeconds()+E);return m};t.addSeconds=function(E){var y=Math.floor(E);var m=this.copy();m.setSeconds(this.getSeconds()+y);return m};t.copy=function(){return f[j].date(this.format("Y-m-d H:i:s"))};t.format=function(m){return f[j].format(this,m)};t.formatUTC=function(m){return f[j].format(this,m,true)};t.incrementBy=function(F,y){if(y!==undefined&&(isNaN(Number(y))||!(Number(y)!==0))){return this}if(!(typeof F=="string"||typeof F=="number")&&(F==null||F==undefined||F==false||!("toString" in F))){return this.copy()}var s=F.split(" ");var m=Number(s[0]);var E=s[1]||"hour";if(y!==null&&y!==undefined&&y!==false&&!isNaN(y)){m=m*y}if(m!==0){switch(E.toString().replace(/s$/,"").toLowerCase()){case"sec":case"second":return this.addMinutes(m/60);case"min":case"minute":return this.addMinutes(m);case"hour":return this.addHours(m);case"day":return this.addDays(m);case"week":return this.addDays(m*7);case"month":return this.addMonths(m);case"year":return this.addYears(m)}}return this.copy()};t.getIncrementBetween=function(s,F){if(!(s instanceof Date)||!F){return 0}var y=F.split(" ");var m=Number(y[0]);var E=y[1]||"hour";if(m!==0){switch(E.toString().replace(/s$/,"").toLowerCase()){case"sec":case"second":return((this.getMinutesBetween(s)/60)/m);case"min":case"minute":return(this.getMinutesBetween(s)/m);case"hour":return(this.getHoursBetween(s)/m);case"day":return(this.getDaysBetween(s)/m);case"week":return((this.getDaysBetween(s)/7)/m);case"month":return(this.getMonthsBetween(s)/m);case"year":return(this.getYearsBetween(s)/m)}}return Infinity};t.roundToIncrement=function(K){if(!(typeof K=="string"||typeof K=="number")&&(K==null||K==undefined||K==false||!("toString" in K))){return this.copy()}var I=K.split(" ");var M=Number(I[0]);var L=I[1]||"hour";var F=this.getTime();if(M!==0){var G=0;switch(L.toString().replace(/s$/,"").toLowerCase()){case"sec":case"second":G=1000*M;break;case"min":case"minute":G=60000*M;break;case"hour":G=3600000*M;break;case"day":G=86400000*M;return f[j].date(new Date((Math.round((F+43200000)/G)*G))).addHours(-12);case"week":var s=this.getDay();var E=null;if(s<3){E=this.addDays(0-s)}else{if(s>3){E=this.addDays(7-s)}else{E=this.addDays(this.getHours()>=12?7-s:0-s)}}E.setHours(0,0,0,0);return E;break;case"month":var H=f[j].date(this.format("Y-m-01 00:00:00"));var m=H.getDaysBetween(H.addMonths(1))/2;if(this.getDate()>=m){return H.addMonths(1)}else{return H}break;case"year":var J=f[j].date(this.format("Y-01-01 00:00:00"));var m=J.getDaysBetween(J.addYears(1))/2;var y=J.getDaysBetween(this);if(y>=m){return J.addYears(1)}else{return J}break}return f[j].date(new Date((Math.round(F/G)*G)))}return this};return t};f[j].incrementsIn=function(n,l){var m=f[j].date("1970-01-01 00:00:00");return m.getIncrementBetween(m.incrementBy(n),l)}})(jQuery);;
/* http://keith-wood.name/icalendar.html
   iCalendar processing for jQuery v1.1.1.
   Written by Keith Wood (kbwood{at}iinet.com.au) October 2008.
   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and 
   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. 
   Please attribute the author if you use it. */
(function ($) { var p = 'icalendar'; var q = 'icalendar-flash-copy'; function iCalendar() { this._defaults = { sites: [], icons: 'icalendar.png', iconSize: 16, target: '_blank', compact: false, popup: false, popupText: 'Send to my calendar...', tipPrefix: '', echoUrl: '', echoField: '', start: null, end: null, title: '', summary: '', description: '', location: '', url: '', contact: '', recurrence: null, copyConfirm: 'The event will be copied to your clipboard. Continue?', copySucceeded: 'The event has been copied to your clipboard', copyFailed: 'Failed to copy the event to the clipboard\n', copyFlash: 'clipboard.swf', copyUnavailable: 'The clipboard is unavailable, please copy the event details from below:\n' }; this._sites = { 'google': { display: 'Google', icon: 0, override: null, url: 'http://www.google.com/calendar/event?action=TEMPLATE' + '&amp;text={t}&amp;dates={s}/{e}&amp;details={d}&amp;location={l}&amp;sprop=website:{u}' }, 'icalendar': { display: 'iCalendar', icon: 1, override: null, url: 'echo' }, 'outlook': { display: 'Outlook', icon: 2, override: null, url: 'echo' }, 'yahoo': { display: 'Yahoo', icon: 3, override: yahooOverride, url: 'http://calendar.yahoo.com/?v=60&amp;view=d&amp;type=20' + '&amp;title={t}&amp;st={s}&amp;dur={p}&amp;desc={d}&amp;in_loc={l}&amp;url={u}&amp;rpat={r}' } } } var r = [{ method: 'Seconds', factor: 1 }, { method: 'Minutes', factor: 60 }, { method: 'Hours', factor: 3600 }, { method: 'Date', factor: 86400 }, { method: 'Month', factor: 1 }, { method: 'FullYear', factor: 12 }, { method: 'Date', factor: 604800 }]; var s = 0; var t = 1; var u = 2; var w = 3; var x = 4; var y = 5; var z = 6; $.extend(iCalendar.prototype, { markerClassName: 'hasICalendar', setDefaults: function (a) { extendRemove(this._defaults, a || {}); return this }, addSite: function (a, b, c, d, e) { this._sites[a] = { display: b, icon: c, override: e, url: d }; return this }, getSites: function () { return this._sites }, _attachICalendar: function (a, b) { a = $(a); if (a.hasClass(this.markerClassName)) { return } a.addClass(this.markerClassName); this._updateICalendar(a, b) }, _changeICalendar: function (a, b) { a = $(a); if (!a.hasClass(this.markerClassName)) { return } this._updateICalendar(a, b) }, _updateICalendar: function (i, j) { j = extendRemove($.extend({}, this._defaults, $.data(i[0], p) || {}), j); $.data(i[0], p, j); var k = j.sites || this._defaults.sites; if (k.length == 0) { $.each(this._sites, function (a) { k[k.length] = a }) } var l = function (b, c) { var d = { t: encodeURIComponent(j.title), d: encodeURIComponent(j.description), s: $.icalendar.formatDateTime(j.start), e: $.icalendar.formatDateTime(j.end), p: $.icalendar.calculateDuration(j.start, j.end), l: encodeURIComponent(j.location), u: encodeURIComponent(j.url), c: encodeURIComponent(j.contact), r: makeRecurrence(j.recurrence) }; if (b.override) { b.override.apply(i, [d, j]) } var e = b.url; $.each(d, function (n, v) { var a = new RegExp('\\{' + n + '\\}', 'g'); e = e.replace(a, v) }); var e = (b.url == 'echo' ? '#' : e); var f = $('<li></li>'); var g = $('<a href="' + e + '" title="' + j.tipPrefix + b.display + '"' + (b.url == 'echo' ? '' : ' target="' + j._target + '"') + '></a>'); if (b.url == 'echo') { g.click(function () { return $.icalendar._echo(i[0], c) }) } var h = ''; if (b.icon != null) { if (typeof b.icon == 'number') { h += '<span style="background: ' + 'transparent url(' + j.icons + ') no-repeat -' + (b.icon * j.iconSize) + 'px 0px;' + ($.browser.mozilla && $.browser.version < '1.9' ? ' padding-left: ' + j.iconSize + 'px; padding-bottom: ' + Math.max(0, (j.iconSize / 2) - 5) + 'px;' : '') + '"></span>' } else { h += '<img src="' + b.icon + '"' + (($.browser.mozilla && $.browser.version < '1.9') || ($.browser.msie && $.browser.version < '7.0') ? ' style="vertical-align: bottom;"' : ($.browser.msie ? ' style="vertical-align: middle;"' : ($.browser.opera || $.browser.safari ? ' style="vertical-align: baseline;"' : ''))) + '/>' } h += (j.compact ? '' : '&#xa0;') } g.html(h + (j.compact ? '' : b.display)); f.append(g); return f }; var m = $('<ul class="icalendar_list' + (j.compact ? ' icalendar_compact' : '') + '"></ul>'); var o = this._sites; $.each(k, function (a, b) { m.append(l(o[b], b)) }); i.empty().append(m); if (j.popup) { m.before('<span class="icalendar_popup_text">' + j.popupText + '</span>').wrap('<div class="icalendar_popup"></div>'); i.click(function () { var a = $(this); var b = a.offset(); $('.icalendar_popup', a).css('left', b.left).css('top', b.top + a.outerHeight()).toggle() }) } }, _destroyICalendar: function (a) { a = $(a); if (!a.hasClass(this.markerClassName)) { return } a.removeClass(this.markerClassName).empty(); $.removeData(a[0], p) }, _echo: function (a, b) { var c = $.data(a, p); var d = makeICalendar(c); if (c.echoUrl) { window.location.href = c.echoUrl + '?content=' + escape(d) } else if (c.echoField) { $(c.echoField).val(d) } else if (!c.copyFlash) { alert(c.copyUnavailable + d) } else if (confirm(c.copyConfirm)) { var e = ''; if (e = copyViaFlash(d, c.copyFlash)) { alert(c.copyFailed + e) } else { alert(c.copySucceeded) } } return false }, _ensureTwo: function (a) { return (a < 10 ? '0' : '') + a }, formatDate: function (a, b) { return (!a ? '' : '' + a.getFullYear() + this._ensureTwo(a.getMonth() + 1) + this._ensureTwo(a.getDate())) }, formatDateTime: function (a, b) { return (!a ? '' : (b ? '' + a.getFullYear() + this._ensureTwo(a.getMonth() + 1) + this._ensureTwo(a.getDate()) + 'T' + this._ensureTwo(a.getHours()) + this._ensureTwo(a.getMinutes()) + this._ensureTwo(a.getSeconds()) : '' + a.getUTCFullYear() + this._ensureTwo(a.getUTCMonth() + 1) + this._ensureTwo(a.getUTCDate()) + 'T' + this._ensureTwo(a.getUTCHours()) + this._ensureTwo(a.getUTCMinutes()) + this._ensureTwo(a.getUTCSeconds()) + 'Z')) }, calculateDuration: function (a, b) { if (!a || !b) { return '' } var c = Math.abs(b.getTime() - a.getTime()) / 1000; var d = Math.floor(c / 86400); c -= d * 86400; var e = Math.floor(c / 3600); c -= e * 3600; var f = Math.floor(c / 60); c -= f * 60; return (a.getTime() > b.getTime() ? '-' : '') + 'P' + (d > 0 ? d + 'D' : '') + (e || f || c ? 'T' + e + 'H' : '') + (f || c ? f + 'M' : '') + (c ? c + 'S' : '') }, addDuration: function (d, e) { if (!e) { return d } var f = new Date(d.getTime()); var g = I.exec(e); if (!g) { throw 'Invalid duration'; } if (g[2] && (g[3] || g[5] || g[6] || g[7])) { throw 'Invalid duration - week must be on its own'; } if (!g[4] && (g[5] || g[6] || g[7])) { throw 'Invalid duration - missing time marker'; } var h = (g[1] == '-' ? -1 : +1); var i = function (a, b, c) { a = parseInt(a); if (!isNaN(a)) { f['setUTC' + c](f['getUTC' + c]() + h * a * b) } }; if (g[2]) { i(g[2], 7, 'Date') } else { i(g[3], 1, 'Date'); i(g[5], 1, 'Hours'); i(g[6], 1, 'Minutes'); i(g[7], 1, 'Seconds') } return f }, parse: function (a) { var b = {}; var c = {}; var d = unfoldLines(a); parseGroup(d, 0, b, c); if (!b.vcalendar) { throw 'Invalid iCalendar data'; } return b.vcalendar }, getWeekOfYear: function (a, b) { return getWeekOfYear(a, b) }, _parseParams: function (a, b) { return parseParams(a, b) } }); function extendRemove(a, b) { $.extend(a, b); for (var c in b) { if (b[c] == null) { a[c] = null } } return a } $.fn.icalendar = function (a) { var b = Array.prototype.slice.call(arguments, 1); return this.each(function () { if (typeof a == 'string') { $.icalendar['_' + a + 'ICalendar'].apply($.icalendar, [this].concat(b)) } else { $.icalendar._attachICalendar(this, a || {}) } }) }; $.icalendar = new iCalendar(); function yahooOverride(b, c) { var d = function (a) { return (a < 10 ? '0' : '') + a }; var e = (c.end ? (c.end.getTime() - c.start.getTime()) / 60000 : 0); b.p = (e ? d(Math.floor(e / 60)) + '' + d(e % 60) : ''); if (b.r) { var f = (c.recurrence.by && c.recurrence.by[0].type == 'day' ? c.recurrence.by[0].values.join('').toLowerCase() : ''); var g = { daily: 'dy', weekly: 'wk', monthly: 'mh', yearly: 'yr' }[c.recurrence.freq]; b.r = (f || g ? d(c.recurrence.interval || 1) + (f || g) : '') } } function makeICalendar(c) { var d = function (a) { var b = ''; while (a.length > 75) { b += a.substr(0, 75) + '\n'; a = ' ' + a.substr(75) } b += a; return b }; return 'BEGIN:VCALENDAR\n' + 'VERSION:2.0\n' + 'PRODID:jquery.icalendar\n' + 'METHOD:PUBLISH\n' + 'BEGIN:VEVENT\n' + 'UID:' + new Date().getTime() + '@' + (window.location.href.replace(/^[^\/]*\/\/([^\/]*)\/.*$/, '$1') || 'localhost') + '\n' + 'DTSTAMP:' + $.icalendar.formatDateTime(new Date()) + '\n' + (c.url ? d('URL:' + c.url) + '\n' : '') + (c.contact ? d('MAILTO:' + c.contact) + '\n' : '') + d('TITLE:' + c.title) + '\n' + 'DTSTART:' + $.icalendar.formatDateTime(c.start) + '\n' + 'DTEND:' + $.icalendar.formatDateTime(c.end) + '\n' + (c.summary ? d('SUMMARY:' + c.summary) + '\n' : '') + (c.description ? d('DESCRIPTION:' + c.description) + '\n' : '') + (c.location ? d('LOCATION:' + c.location) + '\n' : '') + (c.recurrence ? makeRecurrence(c.recurrence) + '\n' : '') + 'END:VEVENT\n' + 'END:VCALENDAR' } function makeRecurrence(a) { if (!a) { return '' } var b = ''; if (a.dates) { b = 'RDATE;VALUE=DATE:'; if (!isArray(a.dates)) { a.dates = [a.dates] } for (var i = 0; i < a.dates.length; i++) { b += (i > 0 ? ',' : '') + $.icalendar.formatDate(a.dates[i]) } } else if (a.times) { b = 'RDATE;VALUE=DATE-TIME:'; if (!isArray(a.times)) { a.times = [a.times] } for (var i = 0; i < a.times.length; i++) { b += (i > 0 ? ',' : '') + $.icalendar.formatDateTime(a.times[i]) } } else if (a.periods) { b = 'RDATE;VALUE=PERIOD:'; if (!isArray(a.periods[0])) { a.periods = [a.periods] } for (var i = 0; i < a.periods.length; i++) { b += (i > 0 ? ',' : '') + $.icalendar.formatDateTime(a.periods[i][0]) + '/' + (a.periods[i][1].constructor != Date ? a.periods[i][1] : $.icalendar.formatDateTime(a.periods[i][1])) } } else { b = 'RRULE:FREQ=' + (a.freq || 'daily').toUpperCase() + (a.interval ? ';INTERVAL=' + a.interval : '') + (a.until ? ';UNTIL=' + $.icalendar.formatDateTime(a.until) : (a.count ? ';COUNT=' + a.count : '')) + (a.weekStart != null ? ';WKST=' + ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'][a.weekStart] : ''); if (a.by) { if (!isArray(a.by)) { a.by = [a.by] } for (var i = 0; i < a.by.length; i++) { if (!isArray(a.by[i].values)) { a.by[i].values = [a.by[i].values] } b += ';BY' + a.by[i].type.toUpperCase() + '=' + a.by[i].values.join(',') } } } return b } function copyViaFlash(a, b) { $('#' + q).remove(); try { $('body').append('<div id="' + q + '"><embed src="' + b + '" FlashVars="clipboard=' + encodeURIComponent(a) + '" width="0" height="0" type="application/x-shockwave-flash"></embed></div>'); return '' } catch (e) { return e } } var A = /^\s(.*)$/; var B = /^([A-Za-z0-9-]+)((?:;[A-Za-z0-9-]+=(?:"[^"]+"|[^";:,]+)(?:,(?:"[^"]+"|[^";:,]+))*)*):(.*)$/; var C = /;([A-Za-z0-9-]+)=((?:"[^"]+"|[^";:,]+)(?:,(?:"[^"]+"|[^";:,]+))*)/g; var D = /,?("[^"]+"|[^";:,]+)/g; var E = /^(\d{4})(\d\d)(\d\d)$/; var F = /^(\d{4})(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)(Z?)$/; var G = /^(\d{4})(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)(Z?)\/(\d{4})(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)(Z?)$/; var H = /^([+-])(\d\d)(\d\d)$/; var I = /^([+-])?P(\d+W)?(\d+D)?(T)?(\d+H)?(\d+M)?(\d+S)?$/; var J = ['class']; function unfoldLines(b) { var c = b.replace(/\r\n/g, '\n').split('\n'); for (var i = c.length - 1; i > 0; i--) { var d = A.exec(c[i]); if (d) { c[i - 1] += d[1]; c[i] = '' } } return $.map(c, function (a, i) { return (a ? a : null) }) } function parseGroup(a, b, c, d) { if (b >= a.length || a[b].indexOf('BEGIN:') != 0) { throw 'Missing group start'; } var e = {}; var f = a[b].substr(6); addEntry(c, f.toLowerCase(), e); b++; while (b < a.length && a[b].indexOf('END:') != 0) { if (a[b].indexOf('BEGIN:') == 0) { b = parseGroup(a, b, e, d) } else { var g = parseEntry(a[b]); addEntry(e, g._name, (g._simple ? g._value : g)) } b++ } if (f == 'VTIMEZONE') { var h = H.exec(e.standard.tzoffsetto); if (h) { d[e.tzid] = (h[1] == '-' ? -1 : +1) * (parseInt(h[2], 10) * 60 + parseInt(h[3], 10)) } } else { for (var i in e) { resolveTimezones(e[i], d) } } if (a[b] != 'END:' + f) { throw 'Missing group end ' + f; } return b } function resolveTimezones(c, d) { if (!c) { return } if (c.tzid && c._value) { var e = d[c.tzid]; var f = function (a, b) { a.setMinutes(a.getMinutes() - e); a._type = b }; if (isArray(c._value)) { for (var i = 0; i < c._value.length; i++) { f(c._value[i], c.tzid) } } else if (c._value.start && c._value.end) { f(c._value.start, c.tzid); f(c._value.end, c.tzid) } else { f(c._value, c.tzid) } } else if (isArray(c)) { for (var i = 0; i < c.length; i++) { resolveTimezones(c[i], d) } } } function addEntry(a, b, c) { if (typeof c == 'string') { c = c.replace(/\\n/g, '\n') } if ($.inArray(b, J) > -1) { b += '_' } if (a[b]) { if (!isArray(a[b]) || a['_' + b + 'IsArray']) { a[b] = [a[b]] } a[b][a[b].length] = c; if (a['_' + b + 'IsArray']) { a['_' + b + 'IsArray'] = undefined } } else { a[b] = c; if (isArray(c)) { a['_' + b + 'IsArray'] = true } } } function parseEntry(a) { var b = {}; var c = B.exec(a); if (!c) { throw 'Missing entry name: ' + a; } b._name = c[1].toLowerCase(); b._value = checkDate(c[3]); b._simple = true; parseParams(b, c[2]); return b } function parseParams(a, b) { var c = C.exec(b); while (c) { var d = []; var e = D.exec(c[2]); while (e) { d.push(checkDate(e[1].replace(/^"(.*)"$/, '$1'))); e = D.exec(c[2]) } a[c[1].toLowerCase()] = (d.length > 1 ? d : d[0]); a._simple = false; c = C.exec(b) } } function checkDate(a) { var b = F.exec(a); if (b) { return makeDate(b) } b = G.exec(a); if (b) { return { start: makeDate(b), end: makeDate(b.slice(7)) } } b = E.exec(a); if (b) { return makeDate(b.concat([0, 0, 0, ''])) } return a } function makeDate(a) { var b = new Date(a[1], a[2] - 1, a[3], a[4], a[5], a[6]); b._type = (a[7] ? 'UTC' : 'float'); return utcDate(b) } function utcDate(a) { a.setMinutes(a.getMinutes() - a.getTimezoneOffset()); return a } function getWeekOfYear(a, b) { b = (b || b == 0 ? b : 1); var c = new Date(a.getFullYear(), a.getMonth(), a.getDate(), (a.getTimezoneOffset() / -60)); var d = new Date(c.getFullYear(), 1 - 1, 4); var e = d.getDay(); d.setDate(4 + b - e - (b > e ? 7 : 0)); if (c < d) { c.setDate(c.getDate() - 3); return getWeekOfYear(c, b) } else if (c > new Date(c.getFullYear(), 12 - 1, 28)) { var f = new Date(c.getFullYear() + 1, 1 - 1, 4); e = f.getDay(); f.setDate(4 + b - e - (b > e ? 7 : 0)); if (c >= f) { return 1 } } return Math.floor(((c - d) / (r[w].factor * 1000)) / 7) + 1 } function isArray(a) { return (a && a.constructor == Array) } })(jQuery);;
$(document).ready(function () {
    $('a').click(function (e) {
        blockScroll();
    });
});
function blockScroll() {
    if ($(this).attr('target') == '_blank') return;
    let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
    let scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
    window.onscroll = function () {
        window.scrollTo(scrollLeft, scrollTop);
    };
    setTimeout(() => {
        window.onscroll = function () { };
    }, 500);
}
function buttonLinkClick(url) {
    blockScroll();
    location.href = url;
}
$(window).on('beforeunload', function () {
    blockScroll();
});;
accessibilityHandler = function () {
    //adding for paragraph ul li tabindex
    //removed from internalParagraph, paragraph, departmentCourses according accessibility file
    var internalParagraphAccessibility = function () {
        $(".paragraphInternalRte ul li").attr("tabindex", "9");
    }
    var keyDownAllowed = true;
    var initSkipMenu = function () {
        var $skipMenuItem = $(".skip li a");
        document.addEventListener("keydown",
            function (e) {
                if (!keyDownAllowed)
                    return;
                keyDownAllowed = false;
                var $skipMenu = $("#skip");
                if (e.keyCode === 9) {
                    $skipMenu.css("height", "16px");
                    $skipMenu.css("overflow", "visible");
                    setTimeout(function () { $($skipMenuItem[0]).focus(); }, 300);
                }
            });
    }
    var initLockCustomSelectPopupFocus = function () {
        setTimeout(() => {
            let inputContainers = $('.inp_select');
            if (inputContainers.length == 0) return;
            inputContainers.each((index, value) => findInput(value));
            $('.custom-select-popup .close-combinations-search').bind('keydown', (e) => {
                let code = e.keyCode;
                if (code == 13) {
                    $(e.target).click();
                    setTimeout(() => { $(e.target).closest('div.inp_select').focus(); }, 50);
                }
            });
        }, 500);
        function findInput(container) {
            container = $(container);
            let elem = container.find('.custom-mobile-input');
            if (elem.length > 0) addCustomSelectCombinationsSearchEvent(elem);
            else {
                setTimeout(() => {
                    elem = container.find('.custom-mobile-input');
                    if (elem.length > 0) addCustomSelectCombinationsSearchEvent(elem);
                }, 2000);
            }
        }
        function addCustomSelectCombinationsSearchEvent(elem) {
            elem.attr('tabindex', '-1');
            elem.parent().bind('keydown', (e) => {
                let code = e.keyCode;
                if (code == 13) {
                    $(e.target).find('.custom-mobile-input').click();
                    setTimeout(() => {
                        $('.custom-select-popup .close-combinations-search:visible').focus();
                    }, 50);
                }
            });   
        }
    }
    var initLockBigDropFocus = function () {
        $('.js-drop-close').bind('focus', (e) => {
            let closeBtn = e.target;
            let container = $(closeBtn).closest('.big-drop');
            let lastFocusElem = container.find(' *[tabindex] ').last();
            lastFocusElem.bind('keydown.initLockBigDropFocus click.initLockBigDropFocus', (e) => { initFocusLastElem(e, closeBtn); });
        });
        function initFocusLastElem(e, closeBtn) {
            if (e.type == 'click' || (e.type == 'keydown' && e.keyCode == 9)) {
                e.preventDefault();
                $(e.target).off('keydown.initLockBigDropFocus');
                $(e.target).off('click.initLockBigDropFocus');
                setTimeout(() => {
                    $(closeBtn).focus();
                }, 50);
            }
        }
        $('.js-drop-close').bind('keydown', (e) => {
            let key = e.keyCode;
            if (key == 13) {
                $(e.target).closest('.big-drop').find(' *[tabindex] ').off('keydown.initLockBigDropFocus');
            }
        });
    }
    var initLockPopupFocus = function () {
        $('.drop-block__body, .mfp-content').bind('keydown',
            function (e) {
                if (e.keyCode === 9 && !e.shiftKey) {
                    e.preventDefault();
                    $(this).find(' *[tabindex] ').last().focus();
                }
            });
        $('body').on('keydown', '.js-open-drop', (event) => {
            if (event.keyCode === 13) {
                $(this).click();
            }
        });
        $(".js-open-drop").bind('keydown', function (e) {
            /*  e.preventDefault();*/
            if (e.keyCode === 13) {
                $(this).click();
            }
        });
        let filter = document.querySelectorAll('.js-filter-check');
        if (filter !== null) {  
            filter.forEach((el) => {
                el.addEventListener('click', () => {
                    if (el.classList.contains('is-active')) {
                        el.setAttribute('aria-checked', 'false');
                    } else {
                        el.setAttribute('aria-checked', 'true');
                    }
                })
            })
        }
    }
    var initUnLockPopupFocus = function () {
        $(document).on('keydown', '.card-item .share-drop__body .share-drop__list .share-link.ics', function (e) {
                if (e.which === 40) {
                    e.preventDefault();
                    // Add your code here to handle the down arrow key press
                    console.log("Down arrow key pressed!");
                    // Add your code here to handle the down arrow key press
                }
                if (e.keyCode==40 || e.keyCode === 9 && !e.shiftKey) {
                    e.preventDefault();
                    $(this).parents(".button.js-open-drop.button--secondary").focus();
                }
            });
    }
    /*
    var initTermsofservice = function () {
        $('input:checkbox[name=termsofservice]').keypress(function (event) {
            var keycode = (event.keyCode ? event.keyCode : event.which);
            if (keycode == 13) {
                Checkbox_to_RadioButton(this, "enter");
            }
            event.stopPropagation();
        });
        $('input:checkbox[name=termsofservice]').click(function () {
            Checkbox_to_RadioButton(this, "click");
        });
        function Checkbox_to_RadioButton(box, myEvent) {
            if (myEvent == "enter") {
                var $box = $(box);
                if ($box.attr('checked'))
                    $box.attr('checked', false);
                else
                    $box.attr('checked', true);
            }
            $('input:checkbox[name=' + box.name + ']').each(function () {
                if (this != box)
                    $(this).attr('checked', false);
            });
        }
    }
    */
    var initAccessibility = function () {
        //internalParagraphAccessibility();
    };
    var initLanguageBar = function() {
        const langBlock = document.querySelector('.lang-block');
        const langList = langBlock!=null?langBlock.querySelector('.lang-block__dropdown'):null;
        const langItems = langList!=null?langList.querySelectorAll('.lang-block__item'):null;
        let selectedLang = langBlock!=null?langBlock.querySelector('.lang-block__item[aria-selected]'):null;
        $('.lang-block .lang-block__body').bind('click',
            function (e) {
                    e.preventDefault();
                    $(this).find('.lang-block__item ').first().focus();
            });
        $(langBlock).bind("keydown", function (event) {
            if (event.keyCode === 38 || event.keyCode === 40) { // up or down arrow key
                event.preventDefault();
                let index = Array.prototype.indexOf.call(langItems, selectedLang);
                if (event.keyCode === 38) { // up arrow key
                    index = index > 0 ? index - 1 : langItems.length - 1;
                } else if (event.keyCode === 40) { // down arrow key
                    index = index < langItems.length - 1 ? index+1  : 0;
                }
                selectedLang.removeAttribute('aria-selected');
                selectedLang = langItems[index];
                selectedLang.setAttribute('aria-selected', 'true');
                langBlock.setAttribute('aria-activedescendant', selectedLang.getAttribute('id'));
                langItems[index].focus();
            }
        });
        if (langItems != null) {
            langItems.forEach(function(langItem) {
                langItem.addEventListener('click',
                    function(event) {
                        selectedLang.removeAttribute('aria-selected');
                        selectedLang = event.target;
                        selectedLang.setAttribute('aria-selected', 'true');
                        langBlock.setAttribute('aria-activedescendant', selectedLang.getAttribute('id'));
                    });
            });
        }
    }
    var initProgramForExcellenceBlockListAccessibility = function () {
        var $tabs = $(".program-block__control.js-cube-control");
        $tabs.bind("click",
            function (e) {
                var $firstItem = $(".program-block__slider .swiper-slide.swiper-slide-active .program-block__board .program-block__title");
                        $firstItem.focus();
            });
        var $cubeLink = $(".program-block__board .link.link--secondary");
        $cubeLink.bind("keydown",
            function (e) {
                var $nextElementTab = $(".program-block__controls .program-block__control.js-cube-control.active");
                $nextElementTab.focus();
            });
        }
    var initMenuAccessibility = function () {
        var $menuButton = $(".header__mid .burger");
        $menuButton.bind("keydown",
            function (e) {
                if (e.keyCode !== 13)
                    return;
                var $main = $("#main");
                if (e.target.classList.contains("open"))
                    $main.attr("aria-hidden", "false");
                else $main.attr("aria-hidden", "true");
                var $firstItem =
                    $(
                        '.nav-menu .nav-menu__column:first-child .nav-menu__column-list:first-child .nav-menu__list-item:first-child');
                setTimeout(() => {
                    var $linkItem = $firstItem.find("a");
                    if ($linkItem && $linkItem.length > 0)
                        $linkItem.focus();
                    else
                        $firstItem.focus();
                },
                    300);
            });
        var focusOnFirstElement = function ($sender) {
            var nextColumn = $sender.closest('.nav-menu__column').next(".nav-menu__column");
            if (nextColumn) {
                setTimeout(function () {
                    var firstInnerItem = $(nextColumn).find(".nav-menu__list-item.is-show")[0];
                    var $navLinkItem = $(firstInnerItem).find("a");
                    if ($navLinkItem && $navLinkItem.length > 0)
                        $navLinkItem.focus();
                    else if (firstInnerItem)
                        $(firstInnerItem).focus();
                },
                    300);
            }
        }
        var focusOnPrevElement = function ($sender) {
            var prevColumn = $sender.closest('.nav-menu__column').prev(".nav-menu__column");
            if (prevColumn) {
                setTimeout(function () {
                    var firstInnerItem = $(prevColumn).find(".nav-menu__list-item.is-show")[0];
                    firstInnerItem = firstInnerItem ?? $(prevColumn).find(".nav-menu__list-item")[0];
                    var $navLinkItem = $(firstInnerItem).find("a");
                    if ($navLinkItem && $navLinkItem.length > 0)
                        $navLinkItem.focus();
                    else if (firstInnerItem)
                        $(firstInnerItem).focus();
                },
                    300);
            }
        }
        var $menuItems = $(".nav-menu__list-item");
        $menuItems.bind("click",
            function () {
                var $this = $(this);
                focusOnFirstElement($this);
            });
        $menuItems.bind("keyup",
            function (e) {
                var $this = $(this);
                if (e.keyCode === 13 || e.keyCode === 37) {
                    focusOnFirstElement($this);
                }
                else if (e.keyCode === 39) {
                    focusOnPrevElement($this);
                }
            });
        var $lastBigLink = $(".nav-menu__big-links .big-link:last-child");
        $lastBigLink.bind("keyup",
            function (e) {
                if (e.keyCode === 9)
                    setTimeout(function () {
                        $menuButton.focus();
                    },
                        300);
            });
        var $favoriteButtonMobileLink = $(".nav-menu__column-list .mob-favorite");
        $favoriteButtonMobileLink.bind("keydown",
            function (e) {
                if (e.keyCode === 9)
                    setTimeout(function () {
                        $(".nav-menu__close").focus();
                    }, 300);
            });
        //var initTooltipMiniAccessibility = function () {
        //    var $openDrops = $(".js-open-drop");
        //    $openDrops.each(function(index) {
        //        var $openDrop = $($openDrops[index]);
        //        var $wrap = $openDrop.closest('.js-help');
        //        var $drop = $wrap.find('.js-drop');
        //        var $link = $drop.find(".link--title");
        //        var $close = $wrap.find('.js-drop-close');
        //        $openDrop.bind("click",
        //            function () {
        //               console.log($close, "close");
        //                setTimeout(function () {
        //                        $close.focus();
        //                    },
        //                    300);
        //            });
        //        $close.bind("keyup",
        //            function (e) {
        //                console.log(e.keyCode, "keyup close");
        //                if (e.keyCode === 9)
        //                    setTimeout(function () {
        //                            $link.focus();
        //                        },
        //                        300);
        //            });
        //        $link.bind("keyup",
        //            function (e) {
        //                console.log(e.keyCode, "keyup link")
        //                if (e.keyCode === 9)
        //                    setTimeout(function () {
        //                            $close.focus();
        //                        },
        //                        300);
        //            });
        //    })
    }
    var scrollToMainContent = function () {
        setTimeout(function () {
            const middleOfPage = Math.max(0, Math.floor(document.documentElement.scrollHeight / 2 - window.innerHeight / 2));
            window.scrollTo({
                top: middleOfPage,
                behavior: 'smooth'
            });
        }, 500);
    }
    var openMainMenu = function () {
        $(".js-close-menu").focus();
    }
    var initConsoleLogForCurrentFocusedElement = function () {
        document.addEventListener('focusin', function () {
            console.log('focused: ', document.activeElement);
        }, true);
        document.addEventListener('arrow.down', function (e) {
            console.log('keydown: ', e.target);
        }, true);
        document.addEventListener('blur', function (e) {
            console.log('blur: ', e.target);
        }, true);
        //document.addEventListener('mouseover', function (e) {
        //    console.log('hover: ', e.target);
        //}, true);
    };
    return {
        init: function () {
            initAccessibility();
            initSkipMenu();
            initLockCustomSelectPopupFocus();
            initLockBigDropFocus();
            initLockPopupFocus();
            initUnLockPopupFocus();
            initMenuAccessibility();
            initConsoleLogForCurrentFocusedElement();
            initLanguageBar();
            initProgramForExcellenceBlockListAccessibility();
            //initTermsofservice();
        },
        scrollTo: function (id, elementToFocus) {
            var target = $("#" + id).offset().top - 65;
            $('body,html').animate({ scrollTop: target }, 500);
            setTimeout(function () { $("#" + id).find(elementToFocus).focus(); }, 700);
        },
        openMainMenu: function () {
            openMainMenu(true);
        },
        scrollToMainContent: function () {
            scrollToMainContent();
        }
    };
}();
$(document).ready(function () {
    accessibilityHandler.init();
});;
headerHandler = function () {
    //This method  redirect to the parallel language page otherwise redirect to the destination language homepage
    var initLanguageDropDown = function () {
        $(".js-language-item:not(.is-current)").bind('click', function (e) {
            e.preventDefault();
            var languageKey = $(this).attr('lang-key');
            var nodeId = $("#currentNodeId").val();
            if ($(this).attr('has-external-link') === 'true') {
                var languageUrl = $(this).attr('language-url');
                if (languageUrl) {
                    window.location.href = languageUrl;
                }
            } else {
                $.ajax({
                    type: "GET",
                    data: {
                        nodeId: nodeId,
                        languageKey: languageKey
                    },
                    dataType: "json",
                    url: "/Umbraco/Surface/GeneralApi/GetNodeUrlByLanguage",
                    contentType: "application/json; charset=utf-8",
                    success: function(data) {
                        console.log("success");
                        location.href = data;
                    },
                    error: function(data) {
                        console.log("error", data);
                    }
                });
            }
        });
        $(".js-language-item").bind('keydown', function(e) {
          /*  e.preventDefault();*/
            if (e.keyCode === 13) {
                $(this).click();
            }
        });
    };
    //code from common.js
    var addingAccessibility = function () {
        const parent = document.querySelector('[data-lang]');
        const langItem = document.querySelectorAll('.js-language-item');
        const langName = document.querySelector('.js-lang-name');
        langItem.forEach((el, i) => {
            const name = el.getAttribute('data-name')
            const id = el.getAttribute('id');
            el.addEventListener('blur', (ev) => {
                setTimeout(() => {
                    if (i + 1 === langItem.length && !document.activeElement.classList.contains('lang-block__item')) {
                        parent.classList.remove('open')
                        parent.setAttribute('aria-expanded', 'false');
                        el.closest('ul').removeAttribute('aria-activedescendant')
                    }
                }, 0)
            })
            el.addEventListener('click', (event) => {
                langName.innerText = name;
                parent.classList.remove('open');
                document.querySelectorAll('.js-lang-item').forEach((elenemt) => {
                    elenemt.classList.remove('is-current');
                    elenemt.removeAttribute('aria-selected');
                })
                el.classList.add('is-current');
                el.setAttribute('aria-selected', 'true');
            });
            el.addEventListener('keydown', (event) => {
                var code = event.keyCode || event.which;
                if (code === 13) {
                    langName.innerText = name;
                    document.querySelectorAll('.js-lang-item').forEach((elenemt) => {
                        elenemt.classList.remove('is-current');
                        elenemt.removeAttribute('aria-selected');
                    })
                    el.classList.add('is-current');
                    el.setAttribute('aria-selected', 'true');
                    setTimeout(() => {
                        parent.classList.remove('open');
                    }, 0)
                }
            });
        })
    }
    return {
        init: function () {
            initLanguageDropDown();
            addingAccessibility();
        }
    };
}();
$(document).ready(function () {
    headerHandler.init();
});;
recaptchaHandler = function () {
    var $grecaptchaBadge = $('.grecaptcha-badge');
    var hideRecaptcha = function () {
        $('.grecaptcha-badge').hide();
        $('.grecaptcha-badge').css("visibility", "hidden");
    }
    var showRecaptcha = function () {
        $('.grecaptcha-badge').show();
        $('.grecaptcha-badge').css("visibility", "visible");
    }
    var setRecaptchaVisibility = function () {
        if ($(".recaptcha-form:visible").length > 0) {
            showRecaptcha();
        } else {
            hideRecaptcha();
        }
    };
    var interestFormClick = function () {
        $(".interestBtn ").bind("click",
            function (e) {
              //  e.preventDefault();
                if ($(".recaptcha-form-clicked:visible").length > 0 && $(".recaptcha-form:visible").length <= 0) {
                    hideRecaptcha();
                } else {
                    showRecaptcha();
                }
            });
    }
    return {
        init: function () {
            setRecaptchaVisibility();
            interestFormClick();
        }
    };
}();
$(document).ready(function () {
    recaptchaHandler.init();
});;
headerSearchHandler = function () {
    //typeahead plugin handler init for search bar autocomplete
    var initTypeahead = function () {
        var pageNodeId = $("#hdnPageNodeId").val();
        var placeHolder = $("#typeahead-search-2").attr("placeholder");
        var sourceData = new Bloodhound({
            datumTokenizer: Bloodhound.tokenizers.obj.whitespace("value"),
            queryTokenizer: Bloodhound.tokenizers.whitespace,
            remote: {
                url: "/umbraco/api/HeaderSearchApi/SearchHeaderAutoComplete?query=%QUERY&searchType=1",
                wildcard: "%QUERY"
            }
        });
        $("#typeahead-search-21").typeahead(null,
            {
                name: "key",
                display: "key",
                source: sourceData,
                templates: {
                    suggestion: function (data) {
                        var content = "";
                        if (data.highlight != null) {
                            if (data.highlight.title)
                                content = data.highlight.title;
                            else content = data.highlight.sections;
                        } else {
                            content = data.title;
                        } 
                        return "<li class=\"typeahead__item typeahead__group - group\" data-group=\"group\" data-index=\"0\" <a href=\"" +
                            data.url +
                            "?q=" +
                            content +
                            "\"><span class=\"typeahead__display\">" +
                            content +
                            "</span></a></li>";
                    }
                }
            });
        $("#typeahead-search-2").bind("focus",
            function () {
                $("#typeahead-search-2").attr("placeholder", "");
            });
        $("#typeahead-search-2").bind("blur",
            function () {
                $("#typeahead-search-2").attr("placeholder", placeHolder);
            });
        $("#typeahead-search-2").bind("blur", function () {
        });
    };
    // Submit query handler, use to remove querystring in case no search query entered
    var initSubmitSearchBar = function () {
        var $txtMainSearch = $("#typeahead-search-2");
        var $submitButton = $("#submitButton");
        $("#mainSearchbar").submit(function (e) {
            if ($txtMainSearch.val() === "") {
                e.preventDefault();
                window.location.href = $(this).attr("action");
            }
        });
        $txtMainSearch.bind("keypress", function (e) {
        });
        //handle search input keypress
        $txtMainSearch.bind("keypress",
            function (e) {
                var $this = $(this);
                var notValid = "[]{}()!?^!/";
                if (notValid.indexOf(e.key) != -1) {
                    e.preventDefault();
                } else {
                    //handle submit form on enter
                    if (e.keyCode === 13) {
                        //replace $query parameter in gtm-parameter attribute
                        $.each($submitButton.get(0).attributes,
                            function () {
                                var attrValue = this.value;
                                if (attrValue.includes("$query")) {
                                    $(this).get(0).nodeValue =
                                        $(this).get(0).nodeValue.replace("$query", $this.get(0).value);
                                }
                            });
                        $("#mainSearchbar").submit();
                    }
                }
            });
        $submitButton.bind("click",
            function () {
                var $this = $(this);
                //replace $query parameter in gtm-parameter attribute
                $.each($this.get(0).attributes,
                    function () {
                        var attrValue = this.value;
                        if (attrValue.includes("$query")) {
                            $(this).get(0).nodeValue =
                                $(this).get(0).nodeValue.replace("$query", $txtMainSearch.get(0).value);
                        }
                    });
            });
    };
    //init typeahead plugin for search input in header
    var initHeaderSearchTypeahead=function() {
        $.typeahead({
            input: '.js-typeahead-search-Header',
            dynamic: true,
            minLength: 1,
           source: {
                ajax: {
                    url: "/umbraco/api/SearchApi/SearchForAutoComplete?cultureCode=" + $("#currentCultureCode").val() +"&term={{query}}",
                    callback: {
                        done: function (data) {
                            var result = [];
                            $.each(data, function (index, value) {
                                result.push({ "name": data[index].title, "groupName": data[index].groupName, "url": data[index].absoluteUrl });
                            });
                            return result;
                        }
                    }
                }
            },
            templateValue: "{{name}}",
            display: ["name"],
          filter: false,
            group: { key: "groupName" },
            // emptyTemplate: $("#header-no-results-text").val() + ' {{query}}',
            callback: {
                onNavigateAfter: function (node, lis, a, item, query, event) {
                    if (~[38, 40].indexOf(event.keyCode)) {
                        var resultList = node.closest("form").find("ul.typeahead__list"),
                            activeLi = lis.filter("li.active"),
                            offsetTop = activeLi[0] && activeLi[0].offsetTop - (resultList.height() / 2) || 0;
                        resultList.scrollTop(offsetTop);
                    }
                },
                onClickAfter: function (node, a, item, event) {
                    event.preventDefault();
                    window.location.href = item.url;
                }
            }
        });
    }
    //init typeahead plugin for search input in home page slider
    var initHomeSearchTypeahead=function() {
        $.typeahead({
            input: '.js-typeahead-search-home',
            minLength: 1,
            dynamic: true,
  source: {
                ajax: {
                    url: "/umbraco/api/SearchApi/SearchForAutoComplete?cultureCode=" + $("#currentCultureCode").val() +"&term={{query}}",
                    callback: {
                        done: function (data) {
                            var result = [];
                            $.each(data, function (index, value) {
                                result.push({
                                    "name": data[index].title, "groupName": data[index].groupName, "url": data[index].absoluteUrl
                                });
                            });
                            return result;
                        }
                    }
                }
            },
            templateValue: "{{name}}",
            //  template:"<a href=\"{{url}}\">{{name}}<a/>",
            display: ["name"],
            filter: false,
            group: { key: "groupName" },
            callback: {
                onNavigateAfter: function (node, lis, a, item, query, event) {
                    if (~[38, 40].indexOf(event.keyCode)) {
                        var resultList = node.closest("form").find("ul.typeahead__list"),
                            activeLi = lis.filter("li.active"),
                            offsetTop = activeLi[0] && activeLi[0].offsetTop - (resultList.height() / 2) || 0;
                        resultList.scrollTop(offsetTop);
                    }
                },
                onClickAfter: function (node, a, item, event) {
                    event.preventDefault();
                    if (item.url != undefined)
                        window.location.href = item.url;
                }
            }
        });
    }
    var navigateNoResultsHandler = function(event) {
        if (event.keyCode === 38 || event.keyCode === 40) {
            var emptySuggestion = $('.typeahead__empty');
            if (emptySuggestion.length) {
                event.preventDefault();
                emptySuggestion.toggleClass('active');
            }
        }
    }
    $('.js-typeahead-search-home').on('keydown', navigateNoResultsHandler);
    $('.js-typeahead-search-Header').on('keydown', navigateNoResultsHandler);
    var initSubmitButtonTypeaheadForms=function() {
        var $form = $(".form--search.typeahead__container");
        $form.bind("submit",
            function (e) {
                e.preventDefault();
                var $this = $(this);
                var inputValue = $this.find(".form__input").val();
                window.location.href = $("#search-results-url").val()+"?q=" + inputValue;
            });
    }
    return {
        init: function () {
            initHeaderSearchTypeahead();
          //  initHomeSearchTypeahead();
            initSubmitButtonTypeaheadForms();
        }
    }
}();
$(document).ready(function () {
    headerSearchHandler.init();
});;
specializationPopUpHandler = function () {
    var openSpecializationPopup = function ($event) {
        var specializationId = $event.attr("specialization-id");
       var elementKey = $(".section--interest[element-key]").attr("element-key");
        var $preLoader = $event.find(".preloader.preloader--mini");
        var displayedCoursesCount = 8;
        $.ajax({
            type: "POST",
            data: JSON.stringify(
                { "elementKey": elementKey, "specializationId": specializationId, "cultureCode": globalVarsHandler.getCultureCode(), "pageNodeId": globalVarsHandler.getNodeId(), "tabId": globalVarsHandler.getTabId() }
            ),
            dataType: "json",
            url: "/Umbraco/Surface/SpecializationsSurface/GetSpecializationPopupData",
            contentType: "application/json; charset=utf-8",
            beforeSend: function () {
                $preLoader.show();
            },
            success: function (data) {
                $preLoader.hide();
                $("#callback-popup").show();
                $("#spec-popup").html("");
                $("#spec-popup").html(data.viewResult);
                //add tooltip html:
                var $tooltipInPopup = $("#spec-popup .computer-popup .mini-tooltip");
                if ($tooltipInPopup != undefined)
                    $tooltipInPopup.parent().html($tooltipInPopup.text().replace("{0}", data.tooltipViewResult));  
                //click handled
                $(".accordion-more").bind("click",
                    function () {
                        var $this = $(this);
                        //show another 10 items
                        var start = displayedCoursesCount - 1;
                        var end = 10;
                        $('.computer-popup__accordion .simple-accordion:gt(' + start + '):lt(' + end + ')')
                            .show();
                        displayedCoursesCount += 10;
                     //hide button at end of items 
                        if (data.coursesCount<displayedCoursesCount)
                            $this.hide();
                    });
             openPopup($event);
            },
            error: function (data) {
                $preLoader.hide();
                $event.show();
                var specializationTitle = $event.find(".spec-item__top").text() + ' ' + $event.find(".spec-item__title").text();
               /* var description = $event.find(".spec-item__text").text();*/
                var noResultsText = $("#no-results-text").val();
                var $popup = $("<div class=\"popup popup--spec\" id=\"spec - popup\">" +
                    " <div class=\"popup__top lazy\" style = \"background-image: url(/content/images/triangles/top-popup.png)\" >" +
                    " <div class=\"title title--bold title--sub title--dark\">" + specializationTitle+
                    "</div>" +
                    "<button class=\"popup__close js-close-popup\">" +
                    "<svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" xmlns=\"http://www.w3.org/2000/svg\">" +
                    "<path d=\"M20.5994 1.39941L1.39941 20.5994M1.39941 1.39941L20.5994 20.5994\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>" +
                    "</svg></button></div >" +
                    " <div class=\"popup__body\"><p style=\"text-align:center\">" + noResultsText+
                    " </p></div>" +
                    "<button title=\"Close (Esc)\" type=\"button\" class=\"mfp-close\">×</button></div>"
                );
                $("#callback-popup").show();
                $("#spec-popup").html("");
                $("#spec-popup").append($popup);
                openPopup($event);
            }
        });
    };
    var initSpecializationBlock = function () {
        $(".specializations-block .swiper-slide .js-open-popup").bind("click",
            function (e) {
                e.preventDefault();
                var $this = $(this);
                openSpecializationPopup($this);
            });
    };
    return {
        init: function () {
            initSpecializationBlock();
        }
    };
}();
$(document).ready(function () {
    specializationPopUpHandler.init();
});;
facultyRequirementsPopUpHandler = function () {
    var openFacultyRequirementPopup = function ($event) {
        var requirementId = $event.attr("requirement-id");
        var elementKey = $(".faculties-block[element-key]").attr("element-key");
        var $preLoader = $event.siblings(".preloader-wrap__mini");
        $("#req-popup").html("");
        $.ajax({
            type: "POST",
            data: JSON.stringify(
                { "elementKey": elementKey, "requirementId": requirementId, "cultureCode": globalVarsHandler.getCultureCode(), "pageNodeId": globalVarsHandler.getNodeId(), "tabId": globalVarsHandler.getTabId() }
            ),
            dataType: "json",
            url: "/Umbraco/Surface/ProgramForExcellenceSurface/GetFacultyRequirementsPopupData",
            contentType: "application/json; charset=utf-8",
            beforeSend: function () {
                $preLoader.show();
                $event.hide();
            },
            success: function (data) {
                $preLoader.hide();
                $event.show();
                $("#callback-popup").show();
                $("#req-popup").html("");
                $("#req-popup").html(data.viewResult);
             openPopup($event);
            },
            error: function (data) {
                $preLoader.hide();
                $event.show();
                var noResultsText = $("#no-results-text").val();
                var $popup = $("<div class=\"popup popup--requirements\" id=\"requirements-popup\">" +
                    " <div class=\"popup__top \" >" +
                    "<button class=\"popup__close js-close-popup\">" +
                    "<svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" xmlns=\"http://www.w3.org/2000/svg\">" +
                    "<path d=\"M20.5994 1.39941L1.39941 20.5994M1.39941 1.39941L20.5994 20.5994\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>" +
                    "</svg></button></div >" +
                    " <div class=\"popup__body\"><h1 style=\"text-align:center\">" + noResultsText +
                    " </h1></div>" +
                    "<button title=\"Close (Esc)\" type=\"button\" class=\"mfp-close\">×</button></div>"
                );
                $("#callback-popup").show();
                $("#req-popup").html("");
                $("#req-popup").append($popup);
                openPopup($event);
            }
        });
    };
    var initFacultyRequirementBlock = function () {
        $(".faculties-block .swiper-slide .link--service").bind("click",
            function (e) {
                e.preventDefault();
                var $this = $(this);
                openFacultyRequirementPopup($this);
            });
    };
    return {
        init: function () {
            initFacultyRequirementBlock();
        }
    };
}();
$(document).ready(function () {
    facultyRequirementsPopUpHandler.init();
});;
window.MessagePopup = function() {
    var getPopupData = function (pageNodeId,cultureCode, $sender) {
        var $preLoader = $sender.find(".preloader-wrap__mini");
        var $content = $sender.find(".content");
        $.ajax({
            type: "POST",
            data: JSON.stringify(
                { "messagePageId": pageNodeId, "cultureCode": cultureCode }
            ),
            dataType: "json",
            url: "/Umbraco/Surface/MessageSurface/GetMessagePopupContent",
            contentType: "application/json; charset=utf-8",
            beforeSend: function () {
               // $preLoader.show();
                //$content.hide();
            },
            success: function (data) {
               //$preLoader.hide();
               //$content.show();
                $("#wrapper-main-popup").html("");
                $("#wrapper-main-popup").html(data.viewResult);
                $("#wrapper-main-popup").show();
                openPopup($sender);
                setTimeout(() => { $('.popup.popup--main.js-dmi.message-popup .popup__close.js-close-popup').focus(); }, 50);
                $("#main-popup .main-popup__iframe iframe").bind("load",
                    function() {
                        var $this = $(this);
                        var $loader = $this.siblings(".preloader-wrap__mini");
                        $loader.hide();
                    });
            },
            error: function (data) {
               //$preLoader.hide();
              // $content.show();
               var title = $sender.find(".short-card__title").text();
                var noResultsText = $("#no-results-text").val();
                var $popup = $("<div class=\"popup popup--spec\" id=\"spec - popup\">" +
                    " <div class=\"popup__top lazy\" style = \"background-image: url(/content/images/triangles/top-popup.png)\" >" +
                    " <div class=\"title title--bold title--sub title--dark\">" + title +
                    "</div>" +
                    "<button class=\"popup__close js-close-popup\">" +
                    "<svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" xmlns=\"http://www.w3.org/2000/svg\">" +
                    "<path d=\"M20.5994 1.39941L1.39941 20.5994M1.39941 1.39941L20.5994 20.5994\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>" +
                    "</svg></button></div >" +
                    " <div class=\"popup__body\"><h1 style=\"text-align:center\">" + noResultsText +
                    " </h1></div>" +
                    "<button title=\"Close (Esc)\" type=\"button\" class=\"mfp-close\">×</button></div>"
                );
                $("#callback-popup").show();
                $("#spec-popup").html("");
                $("#spec-popup").append($popup);
                openPopup($sender);
                setTimeout(() => { $('.popup.popup--main.js-dmi.message-popup .popup__close.js-close-popup').focus(); }, 50);
            }
        });
    }
    var messageClickHandled=function() {
        var $messages = $(".messages-section .short-card, .js-art-section .articles-row__list .link--article,.links-block .links-block__sidebar-top .title-item");
        $messages.bind("click",
            function (e) {
                e.preventDefault();
                var $this = $(this);
                $(".js-art-section .articles-row__list").toggleClass("hovered");
                var pageNodeId = $this.attr("message-node-id");
                var cultureCode = globalVarsHandler.getCultureCode();
                getPopupData(pageNodeId, cultureCode, $this);
            });
    }
    return {
        init: function() {
            messageClickHandled();
        }
    };
}();
$(document).ready(function() {
    MessagePopup.init();
});;
EventFormPopup = function() {
    var getPopupData = function (pageNodeId, cultureCode,$sender) {
        $.ajax({
            type: "POST",
            data: JSON.stringify(
                { "eventFormId": pageNodeId, "cultureCode": cultureCode },
            ),
            dataType: "json",
            url: "/Umbraco/Surface/EventSurface/GetEventFormPopupContent",
            contentType: "application/json; charset=utf-8",
            beforeSend: function () {
            },
            success: function (data) {
                $("#wrapper-event-popup").html("");
                $("#wrapper-event-popup").html(data.viewResult);
                $("#wrapper-event-popup").show();
                //func from vue in main.js file render event-form-component
                window.eventFormApp.init();
                openPopup($sender);
            },
            error: function (data) {
            }
        });
    }
    var eventFormClickHandled =function() {
        var $events = $(".section--cards .button--card");
        $events.bind("click",
            function() {
                var $this = $(this);
                var pageNodeId = $this.attr("event-form-node-id");
                var cultureCode = globalVarsHandler.getCultureCode();
                getPopupData(pageNodeId, cultureCode, $this);
            });
    }
    return {
        init: function() {
            eventFormClickHandled();
        }
    };
}();
$(document).ready(function() {
    EventFormPopup.init();
});;
combinationPopUpHandler = function () {
    var resetPopUp = function () {
        $(".combination-title").text("");
        $(".popup--preview .title--sub-min").text("");
        $(".popup--preview .combination-body").html("");
        $(".computer-popup__buttons").html("");
    }
    var openCombinationPopup = function ($event) {
        resetPopUp();
        var $minTitle = $(".popup--preview .title--sub-min");
        var $title = $(".combination-title");
        var combinationBlock = $event.parents(".service-item--popup");
        var minTitleContent = combinationBlock.attr("body-text-title-popup");
        var titleContent = combinationBlock.find(".service-item__title").text();
        $title.text(titleContent);
        if (minTitleContent != '') {
            $minTitle.text(minTitleContent);
            $minTitle.attr("aria-hidden", false);
        }
        else
            $minTitle.attr("aria-hidden", true);
        $(".popup--preview .combination-body").html(combinationBlock.attr("body-text-popup"));
        $(".computer-popup__buttons").append('<a href=' + combinationBlock.attr("first-degree-link") + ' class="button button--main  " tabindex="0"> <span class="button__text combination-first-degree ">' + combinationBlock.attr("first-degree-link-text") + ' </span> </a>');
        if (combinationBlock.attr("second-degree-link") !== undefined) {
            $(".computer-popup__buttons").append('<a href=' + combinationBlock.attr("second-degree-link") + ' class="button button--main  " tabindex="0"> <span class="button__text combination-second-degree ">' + combinationBlock.attr("second-degree-link-text") + ' </span> </a>');
        }
    };
    var initCombinationBlock = function () {
        $(".service-item--popup[alias='combination'] .service-item__bottom,.service-item--popup[alias='combination']  .service-item__title ").bind("click",
            function (e) {
                e.preventDefault();
                var $this = $(this);
                if (!$this.hasClass("js-dmi"))
                    return;
                openCombinationPopup($this);
            });
    };
    return {
        init: function () {
            initCombinationBlock();
        },
        initCombinationBlock: function () {
            initCombinationBlock();
        }
    };
}();
$(document).ready(function () {
    combinationPopUpHandler.init();
});
window.initCombinationBlock = function () {
    combinationPopUpHandler.initCombinationBlock();
};
iconDescriptionsColumnsHousingHandler = function () {
    var buttonTextChange = function (countOfLostItems) {
        $('.countOfLostItems').text(countOfLostItems);
    };
    var showMoreIconDescriptionsColumns = function (iconDescriptionList, pageSize) {
        // Set the number of items to display on each click
        var itemsPerPage = pageSize;
        var lastDisplayedImage = 0;
        var totalItems = iconDescriptionList;
        // first items after load
        $('.villag-item').slice(lastDisplayedImage, itemsPerPage).css('display', 'flex');
        lastDisplayedImage += itemsPerPage;
        buttonTextChange(iconDescriptionList - lastDisplayedImage);
        // When the "more results" button is clicked, show the next itemsPerPage items
        $('.js-show-all').on('click', function () {
            //show another itemsPerPage items
            $('.villag-item').slice(lastDisplayedImage, lastDisplayedImage + itemsPerPage).css('display', 'flex');
            lastDisplayedImage += itemsPerPage;
            buttonTextChange(iconDescriptionList - lastDisplayedImage);
            // Hide the "more results" button when all items have been displayed
            if (lastDisplayedImage >= totalItems) {
                $('.js-show-all').hide();
            }
        });
    };
    return {
        init: function () {
            var totalItems = parseInt($('section.section--village-list').attr('total-items'));
            var pageSize = parseInt($('section.section--village-list').attr('page-size'));
            if (!isNaN(totalItems) || !isNaN(pageSize)) {
                showMoreIconDescriptionsColumns(totalItems, pageSize);
            } else {
                showMoreIconDescriptionsColumns(9, 2);
            }
        }
    };
}();
$(document).ready(function () {
    iconDescriptionsColumnsHousingHandler.init();
});;
FitOptionsPaginationHousingHandler = function () {
    function fitPaginationInit() {
        const tabBlock = document.querySelector('.fit-block__body.js-tab-block.active');
        if (tabBlock == null)
            return;
        const fitInfo = tabBlock.querySelector('.fit-block__info');
        const pagingButtons = tabBlock.querySelectorAll('.pagination__link:not(.pagination__link--prev):not(.pagination__link--next)');
        const prevButton = tabBlock.querySelector('.pagination__link--prev');
        const nextButton = tabBlock.querySelector('.pagination__link--next');
        var dataPageString = tabBlock.getAttribute('data-page');
        var currentPage = parseInt(dataPageString);
        // Add click event listeners to the paging buttons
        pagingButtons.forEach(button => {
            button.addEventListener('click', (e) => {
                e.preventDefault();
                const page = button.getAttribute('data-current');
                tabBlock.setAttribute('data-page', page);
                fitInfo.querySelectorAll('.page-item:not([data-index="' + page + '"])').forEach(item => {
                    item.style.display = 'none';
                });
                fitInfo.querySelectorAll('.page-item[data-index="' + page + '"]').forEach(item => {
                    item.style.display = 'block';
                });
                pagingButtons.forEach(button => {
                    button.classList.remove('active');
                });
                button.classList.add('active');
                currentPage = page;
                $('html, body').animate({
                    scrollTop: $(".fit-block").offset().top - 50
                }, 1000);
            });
        });
        nextButton.addEventListener('click', (e) => {
            e.preventDefault();
            console.log('pagin next', currentPage, pagingButtons.length)
            if (currentPage >= pagingButtons.length) {
                return;
            }
            const newPage = parseInt(currentPage) + 1;
            const newButton = tabBlock.querySelector('a.pagination__link[data-current="' + newPage + '"]');
            newButton.click();
        });
        prevButton.addEventListener('click', (e) => {
            e.preventDefault();
            if (currentPage <= 1) {
                return;
            }
            const newPage = parseInt(currentPage) - 1;
            const newButton = tabBlock.querySelector('a.pagination__link[data-current="' + newPage + '"]');
            newButton.click();
        });
    }
    var swapTabInit = function () {
        $('.big-tabs--village .js-tab-button').on('click',
            function() {
                setTimeout(function() {
                        fitPaginationInit();
                    },
                    1);
            });
    }
    setTimeout(function() {
            fitPaginationInit();
        },
        1);
    return {
        init: function () {
            swapTabInit();
        }
    };
}();
$(document).ready(function () {
    FitOptionsPaginationHousingHandler.init();
});;
//this handler use for add event to some kinds of clendars
addToCalendarHandler = function () {
    var $allEvents = $(".academic-calendar__category .event-item__buttons ");
    var currentEventJsonData = function ($sender) {
        var eventDetails = {
            title: $sender.attr("event-title"),
            desc: $sender.attr("event-desc"),
            dateStart: $sender.attr("event-start-date"),
            dateEnd: $sender.attr("event-end-date"),
            location: $sender.attr("event-location")
        }
        return eventDetails;
    }
    var isUserSignedIn = false;
    //ics
    var createICSFileForDesktopCalender = function ($sender) {
        var currentEventData = currentEventJsonData($sender.parents(".js-open-drop"));
        var cal = ics();
        cal.addEvent(currentEventData.title, currentEventData.desc, currentEventData.location, new Date(Date.parse(currentEventData.dateStart)), new Date(Date.parse(currentEventData.dateEnd)));
        cal.download();
    }
    //ics multiple events
    var createICSFileAllEventsForDesktopCalender = function () {
        //outlook
        var cal = ics();
        $(".academic-calendar__category .event-item__buttons ").each(function () {
            // cache jquery var
            var $currentEvent = $(this).find('.button--secondary');
            var eventDetails = currentEventJsonData($currentEvent)
            cal.addEvent(eventDetails.title, eventDetails.desc, '', new Date(Date.parse(eventDetails.dateStart)), new Date(Date.parse(eventDetails.dateEnd)));
        });
        cal.download();
    }
    var createICSFileForDesktopCalenderBinding = function () {
        var $icsButton=  $(".share-drop:not(.create-all-events) .share-drop__list .share-link.ics")
        $icsButton.bind("click",
            function (e) {
                e.preventDefault();
                var $this = $(this);
                createICSFileForDesktopCalender($this);
            });
    }
    //google
    var createGoogleEventCalendar = function ($sender) {
        var currentEventData = currentEventJsonData($sender.parents(".js-open-drop"));
        var text = encodeURIComponent(currentEventData.title);
        var startDate = moment(currentEventData.dateStart).format('YYYYMMDDTHHmmss');
        var endDate = moment(currentEventData.dateEnd).format('YYYYMMDDTHHmmss');
        var details = encodeURIComponent(currentEventData.desc);
        var location = encodeURIComponent(currentEventData.location);;
        var googleCalendarUrl = 'http://www.google.com/calendar/event?action=TEMPLATE&text=' + text + '&dates=' + startDate + '/' + endDate + '&details=' + details + '&location=' + location;
        window.open(googleCalendarUrl, '_blank');
    }
    var createGoogleEventCalendarBinding = function () {
        var $googleButton = $(".share-drop:not(.create-all-events) .share-drop__list .share-link.gmail");
        $googleButton.bind("click",
            function (e) {
                e.preventDefault();
                var $this = $(this);
                createGoogleEventCalendar($this);
            });
    }
    //google multiple events
    var createAllEventsGoogleCalendar = function () {
        $allEvents.each(function () {
            var $this = $(this);
            var $sender = $this.find('.button--secondary');
            var currentEventData = currentEventJsonData($sender);
            var request = gapi.client.calendar.events.insert({
                'calendarId': 'primary',
                'resource': currentEventData
            }).then(function (response) {
                console.log('Event created: ', response);
            }).catch(function (error) {
                console.error('Error creating event: ', error);
            });
            request.execute(function (event) {
                console.log('Event created: ' + event.htmlLink);
            });
        })
        alert("עדכנו את לוח השנה שלך בחשבון google ב-" + GoogleEventsCreatedCount + " אירועים חדשים ");
    }
    //outlook
    var createOutlookEventCalendar = function ($sender) {
        var currentEventData = currentEventJsonData($sender.parents(".js-open-drop"));
        var text = encodeURIComponent(currentEventData.title);
        // Split the input into date and time components
        var [datePart, timePart] = currentEventData.dateStart.split(' ');
        // Split the time into hours and minutes
        var [hours, minutes] = timePart.split(':');
        // Create the formatted date string
        var formattedStartDate = `${moment(datePart, 'MM.DD.YYYY').format('YYYY-MM-DD')}T${hours}%3A${minutes}%3A00`;
        // Split the input into date and time components
        var [datePart, timePart] = currentEventData.dateEnd.split(' ');
        // Split the time into hours and minutes
        var [hours, minutes] = timePart.split(':');
        // Create the formatted date string
        var formattedEndDate = `${moment(datePart, 'MM.DD.YYYY').format('YYYY-MM-DD')}T${hours}%3A${minutes}%3A00`;
        var details = encodeURIComponent(currentEventData.desc);
        var location = encodeURIComponent(currentEventData.location);
        var outlookCalendarUrl = 'https://outlook.live.com/calendar/deeplink/compose?path=/calendar/action/compose&rru=add' + '&subject=' + text + '&startdt=' + formattedStartDate + '&enddt=' + formattedEndDate + '&body=' + details + '&location=' + location;
        window.open(outlookCalendarUrl, '_blank');
    }
    var createOutlookEventCalendarBinding = function () {
        var $outlookButton =
            $(".share-drop:not(.create-all-events) .share-drop__list .share-link.outlook")
        $outlookButton.bind("click",
            function (e) {
                e.preventDefault();
                //outlook
                var $this = $(this);
                createOutlookEventCalendar($this);
            });
        $(".all-events .share-drop__list .share-link.outlook").bind("click",
            function (e) {
                e.preventDefault();
                //outlook
            });
    }
    //outlook multiple events
    var createAllEventsForOutlook = function () {
        //outlook
        // Step 1: Set up authentication
        var clientId = '69701444-9b8d-4bff-a435-69b464613dc6';
        var redirectUri = 'http://localhost';
        var graphEndpoint = 'https://graph.microsoft.com/v1.0/';
        // Step 2: Authenticate and obtain an access token
        $.ajax({
            type: 'POST',
            url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data: {
                client_id: clientId,
                redirect_uri: redirectUri,
                grant_type: 'authorization_code',
                client_secret: 'pQJ8Q~AVLjr5dwwHePUb-aFhAIqwli_xuv2f6aR2',
                scope: 'https://graph.microsoft.com/.default'
            },
            success: function (response) {
                var accessToken = response.access_token;
                // Step 3: Create events in the user's calendar
                $allEvents.each(function () {
                    var $this = $(this);
                    var $sender = $this.find('.button--secondary');
                    var currentEventData = currentEventJsonData($sender);
                    $.ajax({
                        type: 'POST',
                        url: graphEndpoint + 'me/calendar/events',
                        headers: {
                            Authorization: 'Bearer ' + accessToken,
                            'Content-Type': 'application/json'
                        },
                        data: JSON.stringify({
                            subject: currentEventData.title,
                            start: {
                                dateTime: currentEventData.dateStart,
                                timeZone: 'Pacific Standard Time'
                            },
                            end: {
                                dateTime: currentEventData.dateEnd,
                                timeZone: 'Pacific Standard Time'
                            }
                        }),
                        success: function (response) {
                            console.log(currentEventData.title+' created: ', response);
                        },
                        error: function (error) {
                            console.log('Error creating :' + currentEventData.title, error);
                        }
                    });
                });
            },
            error: function (error) {
                console.log('Error obtaining access token:', error);
            }
        });
    }
    var createMultipleEventsBinding = function () {
        var $createAllEventsButtons = $(".create-all-events")
        var $outlookButton = $createAllEventsButtons.find(".share-link.outlook")
        var $googleButton = $createAllEventsButtons.find(".share-link.gmail")
        var $icsButton = $createAllEventsButtons.find(".share-link.ics")
        //outlook binding
        $outlookButton.bind("click",
            function (e) {
                e.preventDefault();
                authorizeToOutlook()
            });
        //google binding
        $googleButton.bind("click", function (e) {
            if (!isUserSignedIn) {
                gapi.auth2.getAuthInstance().signIn().then(function () {
                    createAllEventsGoogleCalendar();
                });
            } else { //already authorized user
                createAllEventsGoogleCalendar();
            }
        })
        //ics binding
        $icsButton.bind("click",
            function (e) {
                e.preventDefault();
                createICSFileAllEventsForDesktopCalender()
            });
    }
    var authorizeToOutlook = function () {
        $.ajax({
            type: 'POST',
            url: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data: {
                response_type: "code",
                client_id: "69701444-9b8d-4bff-a435-69b464613dc6",
                redirect_uri: "http://localhost",
                client_secret: "pQJ8Q~AVLjr5dwwHePUb-aFhAIqwli_xuv2f6aR2",
                scope: "offline_access"
            },
            success: function (response) {
                console.log(response)
            },
            error: function (error) {
                console.log('Error obtaining access token:', error);
            }
        });
    }
    window.addToCalendarEvent = function () {
        createICSFileForDesktopCalenderBinding();
        createGoogleEventCalendarBinding();
        createOutlookEventCalendarBinding();
    }
    var googleCalendarSignInStatus = function (status) {
        isUserSignedIn = status;
    };
    var initGoogleCalendarApi = function () {
        var SCOPES = "https://www.googleapis.com/auth/calendar.events";
        //1) init authorization api
        gapi.client.init({
            apiKey: $("#googleApiKey").val(),
            clientId: $("#googleApiOAuthClientIdKey").val(),
            discoveryDocs: ['https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest'],
            scope: SCOPES,
        })
            .then(function () {
            // Listen for sign-in state changes.
            gapi.auth2.getAuthInstance().isSignedIn.listen(googleCalendarSignInStatus);
        }, function (error) {
        });
    };
    var handleClientLoad = function () {
        if ($('.create-all-events').length) {
            gapi.load('client:auth2', initGoogleCalendarApi);
        }
    }
    return {
        init: function () {
            createICSFileForDesktopCalenderBinding();
            createGoogleEventCalendarBinding();
            createOutlookEventCalendarBinding();
            handleClientLoad();
            createMultipleEventsBinding()
        }
    };
}();
$(document).ready(function () {
    addToCalendarHandler.init();
});;
podcastPopup = function () {
    var tabId = globalVarsHandler.getTabId();
    var getPodcastData = function (cultureCode, pageNodeId, mediaCubeElementKey, alias, tabId, $sender) {
        $.ajax({
            type: "POST",
            data: JSON.stringify(
                { "cultureCode": cultureCode, "pageNodeId": pageNodeId, "mediaCubeElementKey": mediaCubeElementKey, "alias": alias, "tabId": tabId }
            ),
            dataType: "json",
            url: "/Umbraco/Surface/BaseArticleSurface/GetPodcastPopupContent",
            contentType: "application/json; charset=utf-8",
            beforeSend: function () {
            },
            success: function (data) {
                var $wrapperPodcastPopup = $("#wrapper-podcast-popup");
                $wrapperPodcastPopup.html("");
                $wrapperPodcastPopup.html(data.viewResult);
                setTimeout(() => {
                    $('.audio-block').toggleClass("open");
                    addEventForPodcast($sender);
                    window.waveSurfer();
                }, 100)
            },
            error: function (data) {
            }
        });
    }
    var podcastClickHandled = function () {
        var $podcasts = $(".js-open-audio-podcast");
        $podcasts.bind("click",
            function () {
                var $this = $(this);
                var pageNodeId = $this.attr("page-node-id");
                var alias = $this.attr("alias");
                var mediaCubeElementKey = $this.attr("media-cube-element-Key")
                var cultureCode = globalVarsHandler.getCultureCode();
                getPodcastData(cultureCode, pageNodeId, mediaCubeElementKey, alias, tabId, $this);
            });
    }
    var addEventForPodcast = function ($this) {
    //copied from common.js (after wavesurfer)
        const auidoTabElem = document.querySelector('.audio-block').querySelectorAll('[tabindex]');
        const tabindex = $($this).attr('tabindex');
        document.querySelector('.audio-block').classList.add('open');
        document.querySelector('.audio-block').querySelector('.js-close-audio').focus();
        auidoTabElem.forEach((el, i) => {
            el.setAttribute('tabindex', tabindex)
        })
        auidoTabElem.forEach((el, i) => {
            el.addEventListener('blur', (ev) => {
                setTimeout(() => {
                    if (i + 1 === auidoTabElem.length && !document.activeElement.closest('.audio-block') || i === 0 && !document.activeElement.closest('.audio-block')) {
                        document.querySelector('.audio-block').querySelector('.js-close-audio').focus();
                    }
                }, 0)
            })
        })
    }
    return {
        init: function () {
            podcastClickHandled();
        }
    };
}();
$(document).ready(function () {
    podcastPopup.init();
});;
window.instagramSectionHandler = function (){
    var instagramTemplate = null;
    var photos = null;
    var photoCount = 0;
    var searchInstagramSection = function(){
        var instagramSection = $("#instagram-section");
        if (instagramSection.length > 0 && instagramSection.attr('instagram-api-enabled')==="true") {
            instagramTemplate = instagramSection;
            photoCount = instagramSection.data('photo-count');
            getInstagramData();
        }
    }
    var getInstagramData = function(){
        $.ajax({
            url: "/api/instagram/GetInstagramData",
            method: "GET",
            data: { photoCount: photoCount },
            success: function(data) {
              photos = data.photos;
              appendPhotos();
            },
            error: function(jqXHR, textStatus, errorThrown) {
              console.log(errorThrown);
            }
        });
    }
    var appendPhotos = function(){
        if(photos.length > 0)
        {
            var swiperWrapper = instagramTemplate.find(".swiper-wrapper")[0];
            var preloader = $('.gallery-slider .swiper-preloader')[0];
            let newPhotoElements = '';
            photos.forEach(photo => {
                newPhotoElements += `
                    <div class="swiper-slide">
                        <div class="slider-link" tabindex="10">
                            <img alt="`
                                +photo.caption+
                            `"loading="lazy" src="`
                                +photo.mediaUrl+
                            `" width="848" height="528">
                        </div>
                    </div>
                `;
            });
            swiperWrapper.insertAdjacentHTML('beforeend', newPhotoElements);
            window.gallerySlider();
        }
    }
    return {
        init: function () {
            searchInstagramSection();
        }
    };
}();
$(document).ready(function () {
    window.instagramSectionHandler.init();
});;
