PageSourceSearch

https://www.nec.edu/wp-content/themes/nec/dist/scripts/main.js?ver=2.0.2

js nec.edu collected 2026-10-02 05:10:02 UTC 2,842,406 bytes, 91,288 lines download raw bytes

vendor: 13,627 bytes, lines 1-513
1/******/ (function(modules) { // webpackBootstrap
2/******/ 	// The module cache
3/******/ 	var installedModules = {};
4/******/
5/******/ 	// The require function
6/******/ 	function __webpack_require__(moduleId) {
7/******/
8/******/ 		// Check if module is in cache
9/******/ 		if(installedModules[moduleId]) {
10/******/ 			return installedModules[moduleId].exports;
11/******/ 		}
12/******/ 		// Create a new module (and put it into the cache)
13/******/ 		var module = installedModules[moduleId] = {
14/******/ 			i: moduleId,
15/******/ 			l: false,
16/******/ 			exports: {}
17/******/ 		};
18/******/
19/******/ 		// Execute the module function
20/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21/******/
22/******/ 		// Flag the module as loaded
23/******/ 		module.l = true;
24/******/
25/******/ 		// Return the exports of the module
26/******/ 		return module.exports;
27/******/ 	}
28/******/
29/******/
30/******/ 	// expose the modules object (__webpack_modules__)
31/******/ 	__webpack_require__.m = modules;
32/******/
33/******/ 	// expose the module cache
34/******/ 	__webpack_require__.c = installedModules;
35/******/
36/******/ 	// define getter function for harmony exports
37/******/ 	__webpack_require__.d = function(exports, name, getter) {
38/******/ 		if(!__webpack_require__.o(exports, name)) {
39/******/ 			Object.defineProperty(exports, name, {
40/******/ 				configurable: false,
41/******/ 				enumerable: true,
42/******/ 				get: getter
43/******/ 			});
44/******/ 		}
45/******/ 	};
46/******/
47/******/ 	// getDefaultExport function for compatibility with non-harmony modules
48/******/ 	__webpack_require__.n = function(module) {
49/******/ 		var getter = module && module.__esModule ?
50/******/ 			function getDefault() { return module['default']; } :
51/******/ 			function getModuleExports() { return module; };
52/******/ 		__webpack_require__.d(getter, 'a', getter);
53/******/ 		return getter;
54/******/ 	};
55/******/
56/******/ 	// Object.prototype.hasOwnProperty.call
57/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
58/******/
59/******/ 	// __webpack_public_path__
60/******/ 	__webpack_require__.p = "/wp-content/themes/nec/dist/";
61/******/
62/******/ 	// Load entry module and return exports
63/******/ 	return __webpack_require__(__webpack_require__.s = 151);
64/******/ })
65/************************************************************************/
66/******/ ([
67/* 0 */
68/***/ (function(module, __webpack_exports__, __webpack_require__) {
69
70"use strict";
71/* WEBPACK VAR INJECTION */(function(module) {var require;//! moment.js
72//! version : 2.29.1
73//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
74//! license : MIT
75//! momentjs.com
76
77var hookCallback;
78
79function hooks() {
80    return hookCallback.apply(null, arguments);
81}
82
83// This is done to register the method called with moment()
84// without creating circular dependencies.
85function setHookCallback(callback) {
86    hookCallback = callback;
87}
88
89function isArray(input) {
90    return (
91        input instanceof Array ||
92        Object.prototype.toString.call(input) === '[object Array]'
93    );
94}
95
96function isObject(input) {
97    // IE8 will treat undefined and null as object if it wasn't for
98    // input != null
99    return (
100        input != null &&
101        Object.prototype.toString.call(input) === '[object Object]'
102    );
103}
104
105function hasOwnProp(a, b) {
106    return Object.prototype.hasOwnProperty.call(a, b);
107}
108
109function isObjectEmpty(obj) {
110    if (Object.getOwnPropertyNames) {
111        return Object.getOwnPropertyNames(obj).length === 0;
112    } else {
113        var k;
114        for (k in obj) {
115            if (hasOwnProp(obj, k)) {
116                return false;
117            }
118        }
119        return true;
120    }
121}
122
123function isUndefined(input) {
124    return input === void 0;
125}
126
127function isNumber(input) {
128    return (
129        typeof input === 'number' ||
130        Object.prototype.toString.call(input) === '[object Number]'
131    );
132}
133
134function isDate(input) {
135    return (
136        input instanceof Date ||
137        Object.prototype.toString.call(input) === '[object Date]'
138    );
139}
140
141function map(arr, fn) {
142    var res = [],
143        i;
144    for (i = 0; i < arr.length; ++i) {
145        res.push(fn(arr[i], i));
146    }
147    return res;
148}
149
150function extend(a, b) {
151    for (var i in b) {
152        if (hasOwnProp(b, i)) {
153            a[i] = b[i];
154        }
155    }
156
157    if (hasOwnProp(b, 'toString')) {
158        a.toString = b.toString;
159    }
160
161    if (hasOwnProp(b, 'valueOf')) {
162        a.valueOf = b.valueOf;
163    }
164
165    return a;
166}
167
168function createUTC(input, format, locale, strict) {
169    return createLocalOrUTC(input, format, locale, strict, true).utc();
170}
171
172function defaultParsingFlags() {
173    // We need to deep clone this object.
174    return {
175        empty: false,
176        unusedTokens: [],
177        unusedInput: [],
178        overflow: -2,
179        charsLeftOver: 0,
180        nullInput: false,
181        invalidEra: null,
182        invalidMonth: null,
183        invalidFormat: false,
184        userInvalidated: false,
185        iso: false,
186        parsedDateParts: [],
187        era: null,
188        meridiem: null,
189        rfc2822: false,
190        weekdayMismatch: false,
191    };
192}
193
194function getParsingFlags(m) {
195    if (m._pf == null) {
196        m._pf = defaultParsingFlags();
197    }
198    return m._pf;
199}
200
201var some;
202if (Array.prototype.some) {
203    some = Array.prototype.some;
204} else {
205    some = function (fun) {
206        var t = Object(this),
207            len = t.length >>> 0,
208            i;
209
210        for (i = 0; i < len; i++) {
211            if (i in t && fun.call(this, t[i], i, t)) {
212                return true;
213            }
214        }
215
216        return false;
217    };
218}
219
220function isValid(m) {
221    if (m._isValid == null) {
222        var flags = getParsingFlags(m),
223            parsedParts = some.call(flags.parsedDateParts, function (i) {
224                return i != null;
225            }),
226            isNowValid =
227                !isNaN(m._d.getTime()) &&
228                flags.overflow < 0 &&
229                !flags.empty &&
230                !flags.invalidEra &&
231                !flags.invalidMonth &&
232                !flags.invalidWeekday &&
233                !flags.weekdayMismatch &&
234                !flags.nullInput &&
235                !flags.invalidFormat &&
236                !flags.userInvalidated &&
237                (!flags.meridiem || (flags.meridiem && parsedParts));
238
239        if (m._strict) {
240            isNowValid =
241                isNowValid &&
242                flags.charsLeftOver === 0 &&
243                flags.unusedTokens.length === 0 &&
244                flags.bigHour === undefined;
245        }
246
247        if (Object.isFrozen == null || !Object.isFrozen(m)) {
248            m._isValid = isNowValid;
249        } else {
250            return isNowValid;
251        }
252    }
253    return m._isValid;
254}
255
256function createInvalid(flags) {
257    var m = createUTC(NaN);
258    if (flags != null) {
259        extend(getParsingFlags(m), flags);
260    } else {
261        getParsingFlags(m).userInvalidated = true;
262    }
263
264    return m;
265}
266
267// Plugins that add properties should also add the key here (null value),
268// so we can properly clone ourselves.
269var momentProperties = (hooks.momentProperties = []),
270    updateInProgress = false;
271
272function copyConfig(to, from) {
273    var i, prop, val;
274
275    if (!isUndefined(from._isAMomentObject)) {
276        to._isAMomentObject = from._isAMomentObject;
277    }
278    if (!isUndefined(from._i)) {
279        to._i = from._i;
280    }
281    if (!isUndefined(from._f)) {
282        to._f = from._f;
283    }
284    if (!isUndefined(from._l)) {
285        to._l = from._l;
286    }
287    if (!isUndefined(from._strict)) {
288        to._strict = from._strict;
289    }
290    if (!isUndefined(from._tzm)) {
291        to._tzm = from._tzm;
292    }
293    if (!isUndefined(from._isUTC)) {
294        to._isUTC = from._isUTC;
295    }
296    if (!isUndefined(from._offset)) {
297        to._offset = from._offset;
298    }
299    if (!isUndefined(from._pf)) {
300        to._pf = getParsingFlags(from);
301    }
302    if (!isUndefined(from._locale)) {
303        to._locale = from._locale;
304    }
305
306    if (momentProperties.length > 0) {
307        for (i = 0; i < momentProperties.length; i++) {
308            prop = momentProperties[i];
309            val = from[prop];
310            if (!isUndefined(val)) {
311                to[prop] = val;
312            }
313        }
314    }
315
316    return to;
317}
318
319// Moment prototype object
320function Moment(config) {
321    copyConfig(this, config);
322    this._d = new Date(config._d != null ? config._d.getTime() : NaN);
323    if (!this.isValid()) {
324        this._d = new Date(NaN);
325    }
326    // Prevent infinite loop in case updateOffset creates new moment
327    // objects.
328    if (updateInProgress === false) {
329        updateInProgress = true;
330        hooks.updateOffset(this);
331        updateInProgress = false;
332    }
333}
334
335function isMoment(obj) {
336    return (
337        obj instanceof Moment || (obj != null && obj._isAMomentObject != null)
338    );
339}
340
341function warn(msg) {
342    if (
343        hooks.suppressDeprecationWarnings === false &&
344        typeof console !== 'undefined' &&
345        console.warn
346    ) {
347        console.warn('Deprecation warning: ' + msg);
348    }
349}
350
351function deprecate(msg, fn) {
352    var firstTime = true;
353
354    return extend(function () {
355        if (hooks.deprecationHandler != null) {
356            hooks.deprecationHandler(null, msg);
357        }
358        if (firstTime) {
359            var args = [],
360                arg,
361                i,
362                key;
363            for (i = 0; i < arguments.length; i++) {
364                arg = '';
365                if (typeof arguments[i] === 'object') {
366                    arg += '\n[' + i + '] ';
367                    for (key in arguments[0]) {
368                        if (hasOwnProp(arguments[0], key)) {
369                            arg += key + ': ' + arguments[0][key] + ', ';
370                        }
371                    }
372                    arg = arg.slice(0, -2); // Remove trailing comma and space
373                } else {
374                    arg = arguments[i];
375                }
376                args.push(arg);
377            }
378            warn(
379                msg +
380                    '\nArguments: ' +
381                    Array.prototype.slice.call(args).join('') +
382                    '\n' +
383                    new Error().stack
384            );
385            firstTime = false;
386        }
387        return fn.apply(this, arguments);
388    }, fn);
389}
390
391var deprecations = {};
392
393function deprecateSimple(name, msg) {
394    if (hooks.deprecationHandler != null) {
395        hooks.deprecationHandler(name, msg);
396    }
397    if (!deprecations[name]) {
398        warn(msg);
399        deprecations[name] = true;
400    }
401}
402
403hooks.suppressDeprecationWarnings = false;
404hooks.deprecationHandler = null;
405
406function isFunction(input) {
407    return (
408        (typeof Function !== 'undefined' && input instanceof Function) ||
409        Object.prototype.toString.call(input) === '[object Function]'
410    );
411}
412
413function set(config) {
414    var prop, i;
415    for (i in config) {
416        if (hasOwnProp(config, i)) {
417            prop = config[i];
418            if (isFunction(prop)) {
419                this[i] = prop;
420            } else {
421                this['_' + i] = prop;
422            }
423        }
424    }
425    this._config = config;
426    // Lenient ordinal parsing accepts just a number in addition to
427    // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
428    // TODO: Remove "ordinalParse" fallback in next major release.
429    this._dayOfMonthOrdinalParseLenient = new RegExp(
430        (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
431            '|' +
432            /\d{1,2}/.source
433    );
434}
435
436function mergeConfigs(parentConfig, childConfig) {
437    var res = extend({}, parentConfig),
438        prop;
439    for (prop in childConfig) {
440        if (hasOwnProp(childConfig, prop)) {
441            if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
442                res[prop] = {};
443                extend(res[prop], parentConfig[prop]);
444                extend(res[prop], childConfig[prop]);
445            } else if (childConfig[prop] != null) {
446                res[prop] = childConfig[prop];
447            } else {
448                delete res[prop];
449            }
450        }
451    }
452    for (prop in parentConfig) {
453        if (
454            hasOwnProp(parentConfig, prop) &&
455            !hasOwnProp(childConfig, prop) &&
456            isObject(parentConfig[prop])
457        ) {
458            // make sure changes to properties don't modify parent config
459            res[prop] = extend({}, res[prop]);
460        }
461    }
462    return res;
463}
464
465function Locale(config) {
466    if (config != null) {
467        this.set(config);
468    }
469}
470
471var keys;
472
473if (Object.keys) {
474    keys = Object.keys;
475} else {
476    keys = function (obj) {
477        var i,
478            res = [];
479        for (i in obj) {
480            if (hasOwnProp(obj, i)) {
481                res.push(i);
482            }
483        }
484        return res;
485    };
486}
487
488var defaultCalendar = {
489    sameDay: '[Today at] LT',
490    nextDay: '[Tomorrow at] LT',
491    nextWeek: 'dddd [at] LT',
492    lastDay: '[Yesterday at] LT',
493    lastWeek: '[Last] dddd [at] LT',
494    sameElse: 'L',
495};
496
497function calendar(key, mom, now) {
498    var output = this._calendar[key] || this._calendar['sameElse'];
499    return isFunction(output) ? output.call(mom, now) : output;
500}
501
502function zeroFill(number, targetLength, forceSign) {
503    var absNumber = '' + Math.abs(number),
504        zerosToFill = targetLength - absNumber.length,
505        sign = number >= 0;
506    return (
507        (sign ? (forceSign ? '+' : '') : '-') +
508        Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) +
509        absNumber
510    );
511}
512
513var formattingTokens =
vendor: 7,523 bytes, lines 513-817
513 /(\[[^\[]*\])|(\\)?([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,
514    localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,
515    formatFunctions = {},
516    formatTokenFunctions = {};
517
518// token:    'M'
519// padded:   ['MM', 2]
520// ordinal:  'Mo'
521// callback: function () { this.month() + 1 }
522function addFormatToken(token, padded, ordinal, callback) {
523    var func = callback;
524    if (typeof callback === 'string') {
525        func = function () {
526            return this[callback]();
527        };
528    }
529    if (token) {
530        formatTokenFunctions[token] = func;
531    }
532    if (padded) {
533        formatTokenFunctions[padded[0]] = function () {
534            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
535        };
536    }
537    if (ordinal) {
538        formatTokenFunctions[ordinal] = function () {
539            return this.localeData().ordinal(
540                func.apply(this, arguments),
541                token
542            );
543        };
544    }
545}
546
547function removeFormattingTokens(input) {
548    if (input.match(/\[[\s\S]/)) {
549        return input.replace(/^\[|\]$/g, '');
550    }
551    return input.replace(/\\/g, '');
552}
553
554function makeFormatFunction(format) {
555    var array = format.match(formattingTokens),
556        i,
557        length;
558
559    for (i = 0, length = array.length; i < length; i++) {
560        if (formatTokenFunctions[array[i]]) {
561            array[i] = formatTokenFunctions[array[i]];
562        } else {
563            array[i] = removeFormattingTokens(array[i]);
564        }
565    }
566
567    return function (mom) {
568        var output = '',
569            i;
570        for (i = 0; i < length; i++) {
571            output += isFunction(array[i])
572                ? array[i].call(mom, format)
573                : array[i];
574        }
575        return output;
576    };
577}
578
579// format date using native date object
580function formatMoment(m, format) {
581    if (!m.isValid()) {
582        return m.localeData().invalidDate();
583    }
584
585    format = expandFormat(format, m.localeData());
586    formatFunctions[format] =
587        formatFunctions[format] || makeFormatFunction(format);
588
589    return formatFunctions[format](m);
590}
591
592function expandFormat(format, locale) {
593    var i = 5;
594
595    function replaceLongDateFormatTokens(input) {
596        return locale.longDateFormat(input) || input;
597    }
598
599    localFormattingTokens.lastIndex = 0;
600    while (i >= 0 && localFormattingTokens.test(format)) {
601        format = format.replace(
602            localFormattingTokens,
603            replaceLongDateFormatTokens
604        );
605        localFormattingTokens.lastIndex = 0;
606        i -= 1;
607    }
608
609    return format;
610}
611
612var defaultLongDateFormat = {
613    LTS: 'h:mm:ss A',
614    LT: 'h:mm A',
615    L: 'MM/DD/YYYY',
616    LL: 'MMMM D, YYYY',
617    LLL: 'MMMM D, YYYY h:mm A',
618    LLLL: 'dddd, MMMM D, YYYY h:mm A',
619};
620
621function longDateFormat(key) {
622    var format = this._longDateFormat[key],
623        formatUpper = this._longDateFormat[key.toUpperCase()];
624
625    if (format || !formatUpper) {
626        return format;
627    }
628
629    this._longDateFormat[key] = formatUpper
630        .match(formattingTokens)
631        .map(function (tok) {
632            if (
633                tok === 'MMMM' ||
634                tok === 'MM' ||
635                tok === 'DD' ||
636                tok === 'dddd'
637            ) {
638                return tok.slice(1);
639            }
640            return tok;
641        })
642        .join('');
643
644    return this._longDateFormat[key];
645}
646
647var defaultInvalidDate = 'Invalid date';
648
649function invalidDate() {
650    return this._invalidDate;
651}
652
653var defaultOrdinal = '%d',
654    defaultDayOfMonthOrdinalParse = /\d{1,2}/;
655
656function ordinal(number) {
657    return this._ordinal.replace('%d', number);
658}
659
660var defaultRelativeTime = {
661    future: 'in %s',
662    past: '%s ago',
663    s: 'a few seconds',
664    ss: '%d seconds',
665    m: 'a minute',
666    mm: '%d minutes',
667    h: 'an hour',
668    hh: '%d hours',
669    d: 'a day',
670    dd: '%d days',
671    w: 'a week',
672    ww: '%d weeks',
673    M: 'a month',
674    MM: '%d months',
675    y: 'a year',
676    yy: '%d years',
677};
678
679function relativeTime(number, withoutSuffix, string, isFuture) {
680    var output = this._relativeTime[string];
681    return isFunction(output)
682        ? output(number, withoutSuffix, string, isFuture)
683        : output.replace(/%d/i, number);
684}
685
686function pastFuture(diff, output) {
687    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
688    return isFunction(format) ? format(output) : format.replace(/%s/i, output);
689}
690
691var aliases = {};
692
693function addUnitAlias(unit, shorthand) {
694    var lowerCase = unit.toLowerCase();
695    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
696}
697
698function normalizeUnits(units) {
699    return typeof units === 'string'
700        ? aliases[units] || aliases[units.toLowerCase()]
701        : undefined;
702}
703
704function normalizeObjectUnits(inputObject) {
705    var normalizedInput = {},
706        normalizedProp,
707        prop;
708
709    for (prop in inputObject) {
710        if (hasOwnProp(inputObject, prop)) {
711            normalizedProp = normalizeUnits(prop);
712            if (normalizedProp) {
713                normalizedInput[normalizedProp] = inputObject[prop];
714            }
715        }
716    }
717
718    return normalizedInput;
719}
720
721var priorities = {};
722
723function addUnitPriority(unit, priority) {
724    priorities[unit] = priority;
725}
726
727function getPrioritizedUnits(unitsObj) {
728    var units = [],
729        u;
730    for (u in unitsObj) {
731        if (hasOwnProp(unitsObj, u)) {
732            units.push({ unit: u, priority: priorities[u] });
733        }
734    }
735    units.sort(function (a, b) {
736        return a.priority - b.priority;
737    });
738    return units;
739}
740
741function isLeapYear(year) {
742    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
743}
744
745function absFloor(number) {
746    if (number < 0) {
747        // -0 -> 0
748        return Math.ceil(number) || 0;
749    } else {
750        return Math.floor(number);
751    }
752}
753
754function toInt(argumentForCoercion) {
755    var coercedNumber = +argumentForCoercion,
756        value = 0;
757
758    if (coercedNumber !== 0 && isFinite(coercedNumber)) {
759        value = absFloor(coercedNumber);
760    }
761
762    return value;
763}
764
765function makeGetSet(unit, keepTime) {
766    return function (value) {
767        if (value != null) {
768            set$1(this, unit, value);
769            hooks.updateOffset(this, keepTime);
770            return this;
771        } else {
772            return get(this, unit);
773        }
774    };
775}
776
777function get(mom, unit) {
778    return mom.isValid()
779        ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]()
780        : NaN;
781}
782
783function set$1(mom, unit, value) {
784    if (mom.isValid() && !isNaN(value)) {
785        if (
786            unit === 'FullYear' &&
787            isLeapYear(mom.year()) &&
788            mom.month() === 1 &&
789            mom.date() === 29
790        ) {
791            value = toInt(value);
792            mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](
793                value,
794                mom.month(),
795                daysInMonth(value, mom.month())
796            );
797        } else {
798            mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
799        }
800    }
801}
802
803// MOMENTS
804
805function stringGet(units) {
806    units = normalizeUnits(units);
807    if (isFunction(this[units])) {
808        return this[units]();
809    }
810    return this;
811}
812
813function stringSet(units, value) {
814    if (typeof units === 'object') {
815        units = normalizeObjectUnits(units);
816        var prioritized = getPrioritizedUnits(units),
817            i
vendor: 5,387 bytes, lines 817-1019
817;
818        for (i = 0; i < prioritized.length; i++) {
819            this[prioritized[i].unit](units[prioritized[i].unit]);
820        }
821    } else {
822        units = normalizeUnits(units);
823        if (isFunction(this[units])) {
824            return this[units](value);
825        }
826    }
827    return this;
828}
829
830var match1 = /\d/, //       0 - 9
831    match2 = /\d\d/, //      00 - 99
832    match3 = /\d{3}/, //     000 - 999
833    match4 = /\d{4}/, //    0000 - 9999
834    match6 = /[+-]?\d{6}/, // -999999 - 999999
835    match1to2 = /\d\d?/, //       0 - 99
836    match3to4 = /\d\d\d\d?/, //     999 - 9999
837    match5to6 = /\d\d\d\d\d\d?/, //   99999 - 999999
838    match1to3 = /\d{1,3}/, //       0 - 999
839    match1to4 = /\d{1,4}/, //       0 - 9999
840    match1to6 = /[+-]?\d{1,6}/, // -999999 - 999999
841    matchUnsigned = /\d+/, //       0 - inf
842    matchSigned = /[+-]?\d+/, //    -inf - inf
843    matchOffset = /Z|[+-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
844    matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, // +00 -00 +00:00 -00:00 +0000 -0000 or Z
845    matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
846    // any word (or two) characters or numbers including two/three word month in arabic.
847    // includes scottish gaelic two word and hyphenated months
848    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,
849    regexes;
850
851regexes = {};
852
853function addRegexToken(token, regex, strictRegex) {
854    regexes[token] = isFunction(regex)
855        ? regex
856        : function (isStrict, localeData) {
857              return isStrict && strictRegex ? strictRegex : regex;
858          };
859}
860
861function getParseRegexForToken(token, config) {
862    if (!hasOwnProp(regexes, token)) {
863        return new RegExp(unescapeFormat(token));
864    }
865
866    return regexes[token](config._strict, config._locale);
867}
868
869// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
870function unescapeFormat(s) {
871    return regexEscape(
872        s
873            .replace('\\', '')
874            .replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (
875                matched,
876                p1,
877                p2,
878                p3,
879                p4
880            ) {
881                return p1 || p2 || p3 || p4;
882            })
883    );
884}
885
886function regexEscape(s) {
887    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
888}
889
890var tokens = {};
891
892function addParseToken(token, callback) {
893    var i,
894        func = callback;
895    if (typeof token === 'string') {
896        token = [token];
897    }
898    if (isNumber(callback)) {
899        func = function (input, array) {
900            array[callback] = toInt(input);
901        };
902    }
903    for (i = 0; i < token.length; i++) {
904        tokens[token[i]] = func;
905    }
906}
907
908function addWeekParseToken(token, callback) {
909    addParseToken(token, function (input, array, config, token) {
910        config._w = config._w || {};
911        callback(input, config._w, config, token);
912    });
913}
914
915function addTimeToArrayFromToken(token, input, config) {
916    if (input != null && hasOwnProp(tokens, token)) {
917        tokens[token](input, config._a, config, token);
918    }
919}
920
921var YEAR = 0,
922    MONTH = 1,
923    DATE = 2,
924    HOUR = 3,
925    MINUTE = 4,
926    SECOND = 5,
927    MILLISECOND = 6,
928    WEEK = 7,
929    WEEKDAY = 8;
930
931function mod(n, x) {
932    return ((n % x) + x) % x;
933}
934
935var indexOf;
936
937if (Array.prototype.indexOf) {
938    indexOf = Array.prototype.indexOf;
939} else {
940    indexOf = function (o) {
941        // I know
942        var i;
943        for (i = 0; i < this.length; ++i) {
944            if (this[i] === o) {
945                return i;
946            }
947        }
948        return -1;
949    };
950}
951
952function daysInMonth(year, month) {
953    if (isNaN(year) || isNaN(month)) {
954        return NaN;
955    }
956    var modMonth = mod(month, 12);
957    year += (month - modMonth) / 12;
958    return modMonth === 1
959        ? isLeapYear(year)
960            ? 29
961            : 28
962        : 31 - ((modMonth % 7) % 2);
963}
964
965// FORMATTING
966
967addFormatToken('M', ['MM', 2], 'Mo', function () {
968    return this.month() + 1;
969});
970
971addFormatToken('MMM', 0, 0, function (format) {
972    return this.localeData().monthsShort(this, format);
973});
974
975addFormatToken('MMMM', 0, 0, function (format) {
976    return this.localeData().months(this, format);
977});
978
979// ALIASES
980
981addUnitAlias('month', 'M');
982
983// PRIORITY
984
985addUnitPriority('month', 8);
986
987// PARSING
988
989addRegexToken('M', match1to2);
990addRegexToken('MM', match1to2, match2);
991addRegexToken('MMM', function (isStrict, locale) {
992    return locale.monthsShortRegex(isStrict);
993});
994addRegexToken('MMMM', function (isStrict, locale) {
995    return locale.monthsRegex(isStrict);
996});
997
998addParseToken(['M', 'MM'], function (input, array) {
999    array[MONTH] = toInt(input) - 1;
1000});
1001
1002addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
1003    var month = config._locale.monthsParse(input, token, config._strict);
1004    // if we didn't find a month name, mark the date as invalid.
1005    if (month != null) {
1006        array[MONTH] = month;
1007    } else {
1008        getParsingFlags(config).invalidMonth = input;
1009    }
1010});
1011
1012// LOCALES
1013
1014var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
1015        '_'
1016    ),
1017    defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split(
1018        '_'
1019    
vendor: 12,245 bytes, lines 1019-1461
1019),
1020    MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,
1021    defaultMonthsShortRegex = matchWord,
1022    defaultMonthsRegex = matchWord;
1023
1024function localeMonths(m, format) {
1025    if (!m) {
1026        return isArray(this._months)
1027            ? this._months
1028            : this._months['standalone'];
1029    }
1030    return isArray(this._months)
1031        ? this._months[m.month()]
1032        : this._months[
1033              (this._months.isFormat || MONTHS_IN_FORMAT).test(format)
1034                  ? 'format'
1035                  : 'standalone'
1036          ][m.month()];
1037}
1038
1039function localeMonthsShort(m, format) {
1040    if (!m) {
1041        return isArray(this._monthsShort)
1042            ? this._monthsShort
1043            : this._monthsShort['standalone'];
1044    }
1045    return isArray(this._monthsShort)
1046        ? this._monthsShort[m.month()]
1047        : this._monthsShort[
1048              MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'
1049          ][m.month()];
1050}
1051
1052function handleStrictParse(monthName, format, strict) {
1053    var i,
1054        ii,
1055        mom,
1056        llc = monthName.toLocaleLowerCase();
1057    if (!this._monthsParse) {
1058        // this is not used
1059        this._monthsParse = [];
1060        this._longMonthsParse = [];
1061        this._shortMonthsParse = [];
1062        for (i = 0; i < 12; ++i) {
1063            mom = createUTC([2000, i]);
1064            this._shortMonthsParse[i] = this.monthsShort(
1065                mom,
1066                ''
1067            ).toLocaleLowerCase();
1068            this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
1069        }
1070    }
1071
1072    if (strict) {
1073        if (format === 'MMM') {
1074            ii = indexOf.call(this._shortMonthsParse, llc);
1075            return ii !== -1 ? ii : null;
1076        } else {
1077            ii = indexOf.call(this._longMonthsParse, llc);
1078            return ii !== -1 ? ii : null;
1079        }
1080    } else {
1081        if (format === 'MMM') {
1082            ii = indexOf.call(this._shortMonthsParse, llc);
1083            if (ii !== -1) {
1084                return ii;
1085            }
1086            ii = indexOf.call(this._longMonthsParse, llc);
1087            return ii !== -1 ? ii : null;
1088        } else {
1089            ii = indexOf.call(this._longMonthsParse, llc);
1090            if (ii !== -1) {
1091                return ii;
1092            }
1093            ii = indexOf.call(this._shortMonthsParse, llc);
1094            return ii !== -1 ? ii : null;
1095        }
1096    }
1097}
1098
1099function localeMonthsParse(monthName, format, strict) {
1100    var i, mom, regex;
1101
1102    if (this._monthsParseExact) {
1103        return handleStrictParse.call(this, monthName, format, strict);
1104    }
1105
1106    if (!this._monthsParse) {
1107        this._monthsParse = [];
1108        this._longMonthsParse = [];
1109        this._shortMonthsParse = [];
1110    }
1111
1112    // TODO: add sorting
1113    // Sorting makes sure if one month (or abbr) is a prefix of another
1114    // see sorting in computeMonthsParse
1115    for (i = 0; i < 12; i++) {
1116        // make the regex if we don't have it already
1117        mom = createUTC([2000, i]);
1118        if (strict && !this._longMonthsParse[i]) {
1119            this._longMonthsParse[i] = new RegExp(
1120                '^' + this.months(mom, '').replace('.', '') + '$',
1121                'i'
1122            );
1123            this._shortMonthsParse[i] = new RegExp(
1124                '^' + this.monthsShort(mom, '').replace('.', '') + '$',
1125                'i'
1126            );
1127        }
1128        if (!strict && !this._monthsParse[i]) {
1129            regex =
1130                '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
1131            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
1132        }
1133        // test the regex
1134        if (
1135            strict &&
1136            format === 'MMMM' &&
1137            this._longMonthsParse[i].test(monthName)
1138        ) {
1139            return i;
1140        } else if (
1141            strict &&
1142            format === 'MMM' &&
1143            this._shortMonthsParse[i].test(monthName)
1144        ) {
1145            return i;
1146        } else if (!strict && this._monthsParse[i].test(monthName)) {
1147            return i;
1148        }
1149    }
1150}
1151
1152// MOMENTS
1153
1154function setMonth(mom, value) {
1155    var dayOfMonth;
1156
1157    if (!mom.isValid()) {
1158        // No op
1159        return mom;
1160    }
1161
1162    if (typeof value === 'string') {
1163        if (/^\d+$/.test(value)) {
1164            value = toInt(value);
1165        } else {
1166            value = mom.localeData().monthsParse(value);
1167            // TODO: Another silent failure?
1168            if (!isNumber(value)) {
1169                return mom;
1170            }
1171        }
1172    }
1173
1174    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
1175    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
1176    return mom;
1177}
1178
1179function getSetMonth(value) {
1180    if (value != null) {
1181        setMonth(this, value);
1182        hooks.updateOffset(this, true);
1183        return this;
1184    } else {
1185        return get(this, 'Month');
1186    }
1187}
1188
1189function getDaysInMonth() {
1190    return daysInMonth(this.year(), this.month());
1191}
1192
1193function monthsShortRegex(isStrict) {
1194    if (this._monthsParseExact) {
1195        if (!hasOwnProp(this, '_monthsRegex')) {
1196            computeMonthsParse.call(this);
1197        }
1198        if (isStrict) {
1199            return this._monthsShortStrictRegex;
1200        } else {
1201            return this._monthsShortRegex;
1202        }
1203    } else {
1204        if (!hasOwnProp(this, '_monthsShortRegex')) {
1205            this._monthsShortRegex = defaultMonthsShortRegex;
1206        }
1207        return this._monthsShortStrictRegex && isStrict
1208            ? this._monthsShortStrictRegex
1209            : this._monthsShortRegex;
1210    }
1211}
1212
1213function monthsRegex(isStrict) {
1214    if (this._monthsParseExact) {
1215        if (!hasOwnProp(this, '_monthsRegex')) {
1216            computeMonthsParse.call(this);
1217        }
1218        if (isStrict) {
1219            return this._monthsStrictRegex;
1220        } else {
1221            return this._monthsRegex;
1222        }
1223    } else {
1224        if (!hasOwnProp(this, '_monthsRegex')) {
1225            this._monthsRegex = defaultMonthsRegex;
1226        }
1227        return this._monthsStrictRegex && isStrict
1228            ? this._monthsStrictRegex
1229            : this._monthsRegex;
1230    }
1231}
1232
1233function computeMonthsParse() {
1234    function cmpLenRev(a, b) {
1235        return b.length - a.length;
1236    }
1237
1238    var shortPieces = [],
1239        longPieces = [],
1240        mixedPieces = [],
1241        i,
1242        mom;
1243    for (i = 0; i < 12; i++) {
1244        // make the regex if we don't have it already
1245        mom = createUTC([2000, i]);
1246        shortPieces.push(this.monthsShort(mom, ''));
1247        longPieces.push(this.months(mom, ''));
1248        mixedPieces.push(this.months(mom, ''));
1249        mixedPieces.push(this.monthsShort(mom, ''));
1250    }
1251    // Sorting makes sure if one month (or abbr) is a prefix of another it
1252    // will match the longer piece.
1253    shortPieces.sort(cmpLenRev);
1254    longPieces.sort(cmpLenRev);
1255    mixedPieces.sort(cmpLenRev);
1256    for (i = 0; i < 12; i++) {
1257        shortPieces[i] = regexEscape(shortPieces[i]);
1258        longPieces[i] = regexEscape(longPieces[i]);
1259    }
1260    for (i = 0; i < 24; i++) {
1261        mixedPieces[i] = regexEscape(mixedPieces[i]);
1262    }
1263
1264    this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
1265    this._monthsShortRegex = this._monthsRegex;
1266    this._monthsStrictRegex = new RegExp(
1267        '^(' + longPieces.join('|') + ')',
1268        'i'
1269    );
1270    this._monthsShortStrictRegex = new RegExp(
1271        '^(' + shortPieces.join('|') + ')',
1272        'i'
1273    );
1274}
1275
1276// FORMATTING
1277
1278addFormatToken('Y', 0, 0, function () {
1279    var y = this.year();
1280    return y <= 9999 ? zeroFill(y, 4) : '+' + y;
1281});
1282
1283addFormatToken(0, ['YY', 2], 0, function () {
1284    return this.year() % 100;
1285});
1286
1287addFormatToken(0, ['YYYY', 4], 0, 'year');
1288addFormatToken(0, ['YYYYY', 5], 0, 'year');
1289addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
1290
1291// ALIASES
1292
1293addUnitAlias('year', 'y');
1294
1295// PRIORITIES
1296
1297addUnitPriority('year', 1);
1298
1299// PARSING
1300
1301addRegexToken('Y', matchSigned);
1302addRegexToken('YY', match1to2, match2);
1303addRegexToken('YYYY', match1to4, match4);
1304addRegexToken('YYYYY', match1to6, match6);
1305addRegexToken('YYYYYY', match1to6, match6);
1306
1307addParseToken(['YYYYY', 'YYYYYY'], YEAR);
1308addParseToken('YYYY', function (input, array) {
1309    array[YEAR] =
1310        input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
1311});
1312addParseToken('YY', function (input, array) {
1313    array[YEAR] = hooks.parseTwoDigitYear(input);
1314});
1315addParseToken('Y', function (input, array) {
1316    array[YEAR] = parseInt(input, 10);
1317});
1318
1319// HELPERS
1320
1321function daysInYear(year) {
1322    return isLeapYear(year) ? 366 : 365;
1323}
1324
1325// HOOKS
1326
1327hooks.parseTwoDigitYear = function (input) {
1328    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
1329};
1330
1331// MOMENTS
1332
1333var getSetYear = makeGetSet('FullYear', true);
1334
1335function getIsLeapYear() {
1336    return isLeapYear(this.year());
1337}
1338
1339function createDate(y, m, d, h, M, s, ms) {
1340    // can't just apply() to create a date:
1341    // https://stackoverflow.com/q/181348
1342    var date;
1343    // the date constructor remaps years 0-99 to 1900-1999
1344    if (y < 100 && y >= 0) {
1345        // preserve leap years using a full 400 year cycle, then reset
1346        date = new Date(y + 400, m, d, h, M, s, ms);
1347        if (isFinite(date.getFullYear())) {
1348            date.setFullYear(y);
1349        }
1350    } else {
1351        date = new Date(y, m, d, h, M, s, ms);
1352    }
1353
1354    return date;
1355}
1356
1357function createUTCDate(y) {
1358    var date, args;
1359    // the Date.UTC function remaps years 0-99 to 1900-1999
1360    if (y < 100 && y >= 0) {
1361        args = Array.prototype.slice.call(arguments);
1362        // preserve leap years using a full 400 year cycle, then reset
1363        args[0] = y + 400;
1364        date = new Date(Date.UTC.apply(null, args));
1365        if (isFinite(date.getUTCFullYear())) {
1366            date.setUTCFullYear(y);
1367        }
1368    } else {
1369        date = new Date(Date.UTC.apply(null, arguments));
1370    }
1371
1372    return date;
1373}
1374
1375// start-of-first-week - start-of-year
1376function firstWeekOffset(year, dow, doy) {
1377    var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
1378        fwd = 7 + dow - doy,
1379        // first-week day local weekday -- which local weekday is fwd
1380        fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
1381
1382    return -fwdlw + fwd - 1;
1383}
1384
1385// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
1386function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
1387    var localWeekday = (7 + weekday - dow) % 7,
1388        weekOffset = firstWeekOffset(year, dow, doy),
1389        dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
1390        resYear,
1391        resDayOfYear;
1392
1393    if (dayOfYear <= 0) {
1394        resYear = year - 1;
1395        resDayOfYear = daysInYear(resYear) + dayOfYear;
1396    } else if (dayOfYear > daysInYear(year)) {
1397        resYear = year + 1;
1398        resDayOfYear = dayOfYear - daysInYear(year);
1399    } else {
1400        resYear = year;
1401        resDayOfYear = dayOfYear;
1402    }
1403
1404    return {
1405        year: resYear,
1406        dayOfYear: resDayOfYear,
1407    };
1408}
1409
1410function weekOfYear(mom, dow, doy) {
1411    var weekOffset = firstWeekOffset(mom.year(), dow, doy),
1412        week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
1413        resWeek,
1414        resYear;
1415
1416    if (week < 1) {
1417        resYear = mom.year() - 1;
1418        resWeek = week + weeksInYear(resYear, dow, doy);
1419    } else if (week > weeksInYear(mom.year(), dow, doy)) {
1420        resWeek = week - weeksInYear(mom.year(), dow, doy);
1421        resYear = mom.year() + 1;
1422    } else {
1423        resYear = mom.year();
1424        resWeek = week;
1425    }
1426
1427    return {
1428        week: resWeek,
1429        year: resYear,
1430    };
1431}
1432
1433function weeksInYear(year, dow, doy) {
1434    var weekOffset = firstWeekOffset(year, dow, doy),
1435        weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
1436    return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
1437}
1438
1439// FORMATTING
1440
1441addFormatToken('w', ['ww', 2], 'wo', 'week');
1442addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
1443
1444// ALIASES
1445
1446addUnitAlias('week', 'w');
1447addUnitAlias('isoWeek', 'W');
1448
1449// PRIORITIES
1450
1451addUnitPriority('week', 5);
1452addUnitPriority('isoWeek', 5);
1453
1454// PARSING
1455
1456addRegexToken('w', match1to2);
1457addRegexToken('ww', match1to2, match2);
1458addRegexToken('W', match1to2);
1459addRegexToken('WW', match1to2, match2);
1460
1461addWeekParseToken(
vendor: 3,089 bytes, lines 1461-1595
1461['w', 'ww', 'W', 'WW'], function (
1462    input,
1463    week,
1464    config,
1465    token
1466) {
1467    week[token.substr(0, 1)] = toInt(input);
1468});
1469
1470// HELPERS
1471
1472// LOCALES
1473
1474function localeWeek(mom) {
1475    return weekOfYear(mom, this._week.dow, this._week.doy).week;
1476}
1477
1478var defaultLocaleWeek = {
1479    dow: 0, // Sunday is the first day of the week.
1480    doy: 6, // The week that contains Jan 6th is the first week of the year.
1481};
1482
1483function localeFirstDayOfWeek() {
1484    return this._week.dow;
1485}
1486
1487function localeFirstDayOfYear() {
1488    return this._week.doy;
1489}
1490
1491// MOMENTS
1492
1493function getSetWeek(input) {
1494    var week = this.localeData().week(this);
1495    return input == null ? week : this.add((input - week) * 7, 'd');
1496}
1497
1498function getSetISOWeek(input) {
1499    var week = weekOfYear(this, 1, 4).week;
1500    return input == null ? week : this.add((input - week) * 7, 'd');
1501}
1502
1503// FORMATTING
1504
1505addFormatToken('d', 0, 'do', 'day');
1506
1507addFormatToken('dd', 0, 0, function (format) {
1508    return this.localeData().weekdaysMin(this, format);
1509});
1510
1511addFormatToken('ddd', 0, 0, function (format) {
1512    return this.localeData().weekdaysShort(this, format);
1513});
1514
1515addFormatToken('dddd', 0, 0, function (format) {
1516    return this.localeData().weekdays(this, format);
1517});
1518
1519addFormatToken('e', 0, 0, 'weekday');
1520addFormatToken('E', 0, 0, 'isoWeekday');
1521
1522// ALIASES
1523
1524addUnitAlias('day', 'd');
1525addUnitAlias('weekday', 'e');
1526addUnitAlias('isoWeekday', 'E');
1527
1528// PRIORITY
1529addUnitPriority('day', 11);
1530addUnitPriority('weekday', 11);
1531addUnitPriority('isoWeekday', 11);
1532
1533// PARSING
1534
1535addRegexToken('d', match1to2);
1536addRegexToken('e', match1to2);
1537addRegexToken('E', match1to2);
1538addRegexToken('dd', function (isStrict, locale) {
1539    return locale.weekdaysMinRegex(isStrict);
1540});
1541addRegexToken('ddd', function (isStrict, locale) {
1542    return locale.weekdaysShortRegex(isStrict);
1543});
1544addRegexToken('dddd', function (isStrict, locale) {
1545    return locale.weekdaysRegex(isStrict);
1546});
1547
1548addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
1549    var weekday = config._locale.weekdaysParse(input, token, config._strict);
1550    // if we didn't get a weekday name, mark the date as invalid
1551    if (weekday != null) {
1552        week.d = weekday;
1553    } else {
1554        getParsingFlags(config).invalidWeekday = input;
1555    }
1556});
1557
1558addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
1559    week[token] = toInt(input);
1560});
1561
1562// HELPERS
1563
1564function parseWeekday(input, locale) {
1565    if (typeof input !== 'string') {
1566        return input;
1567    }
1568
1569    if (!isNaN(input)) {
1570        return parseInt(input, 10);
1571    }
1572
1573    input = locale.weekdaysParse(input);
1574    if (typeof input === 'number') {
1575        return input;
1576    }
1577
1578    return null;
1579}
1580
1581function parseIsoWeekday(input, locale) {
1582    if (typeof input === 'string') {
1583        return locale.weekdaysParse(input) % 7 || 7;
1584    }
1585    return isNaN(input) ? null : input;
1586}
1587
1588// LOCALES
1589function shiftWeekdays(ws, n) {
1590    return ws.slice(n, 7).concat(ws.slice(0, n));
1591}
1592
1593var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
1594        '_'
1595    
vendor: 15,900 bytes, lines 1595-2143
1595),
1596    defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
1597    defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
1598    defaultWeekdaysRegex = matchWord,
1599    defaultWeekdaysShortRegex = matchWord,
1600    defaultWeekdaysMinRegex = matchWord;
1601
1602function localeWeekdays(m, format) {
1603    var weekdays = isArray(this._weekdays)
1604        ? this._weekdays
1605        : this._weekdays[
1606              m && m !== true && this._weekdays.isFormat.test(format)
1607                  ? 'format'
1608                  : 'standalone'
1609          ];
1610    return m === true
1611        ? shiftWeekdays(weekdays, this._week.dow)
1612        : m
1613        ? weekdays[m.day()]
1614        : weekdays;
1615}
1616
1617function localeWeekdaysShort(m) {
1618    return m === true
1619        ? shiftWeekdays(this._weekdaysShort, this._week.dow)
1620        : m
1621        ? this._weekdaysShort[m.day()]
1622        : this._weekdaysShort;
1623}
1624
1625function localeWeekdaysMin(m) {
1626    return m === true
1627        ? shiftWeekdays(this._weekdaysMin, this._week.dow)
1628        : m
1629        ? this._weekdaysMin[m.day()]
1630        : this._weekdaysMin;
1631}
1632
1633function handleStrictParse$1(weekdayName, format, strict) {
1634    var i,
1635        ii,
1636        mom,
1637        llc = weekdayName.toLocaleLowerCase();
1638    if (!this._weekdaysParse) {
1639        this._weekdaysParse = [];
1640        this._shortWeekdaysParse = [];
1641        this._minWeekdaysParse = [];
1642
1643        for (i = 0; i < 7; ++i) {
1644            mom = createUTC([2000, 1]).day(i);
1645            this._minWeekdaysParse[i] = this.weekdaysMin(
1646                mom,
1647                ''
1648            ).toLocaleLowerCase();
1649            this._shortWeekdaysParse[i] = this.weekdaysShort(
1650                mom,
1651                ''
1652            ).toLocaleLowerCase();
1653            this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
1654        }
1655    }
1656
1657    if (strict) {
1658        if (format === 'dddd') {
1659            ii = indexOf.call(this._weekdaysParse, llc);
1660            return ii !== -1 ? ii : null;
1661        } else if (format === 'ddd') {
1662            ii = indexOf.call(this._shortWeekdaysParse, llc);
1663            return ii !== -1 ? ii : null;
1664        } else {
1665            ii = indexOf.call(this._minWeekdaysParse, llc);
1666            return ii !== -1 ? ii : null;
1667        }
1668    } else {
1669        if (format === 'dddd') {
1670            ii = indexOf.call(this._weekdaysParse, llc);
1671            if (ii !== -1) {
1672                return ii;
1673            }
1674            ii = indexOf.call(this._shortWeekdaysParse, llc);
1675            if (ii !== -1) {
1676                return ii;
1677            }
1678            ii = indexOf.call(this._minWeekdaysParse, llc);
1679            return ii !== -1 ? ii : null;
1680        } else if (format === 'ddd') {
1681            ii = indexOf.call(this._shortWeekdaysParse, llc);
1682            if (ii !== -1) {
1683                return ii;
1684            }
1685            ii = indexOf.call(this._weekdaysParse, llc);
1686            if (ii !== -1) {
1687                return ii;
1688            }
1689            ii = indexOf.call(this._minWeekdaysParse, llc);
1690            return ii !== -1 ? ii : null;
1691        } else {
1692            ii = indexOf.call(this._minWeekdaysParse, llc);
1693            if (ii !== -1) {
1694                return ii;
1695            }
1696            ii = indexOf.call(this._weekdaysParse, llc);
1697            if (ii !== -1) {
1698                return ii;
1699            }
1700            ii = indexOf.call(this._shortWeekdaysParse, llc);
1701            return ii !== -1 ? ii : null;
1702        }
1703    }
1704}
1705
1706function localeWeekdaysParse(weekdayName, format, strict) {
1707    var i, mom, regex;
1708
1709    if (this._weekdaysParseExact) {
1710        return handleStrictParse$1.call(this, weekdayName, format, strict);
1711    }
1712
1713    if (!this._weekdaysParse) {
1714        this._weekdaysParse = [];
1715        this._minWeekdaysParse = [];
1716        this._shortWeekdaysParse = [];
1717        this._fullWeekdaysParse = [];
1718    }
1719
1720    for (i = 0; i < 7; i++) {
1721        // make the regex if we don't have it already
1722
1723        mom = createUTC([2000, 1]).day(i);
1724        if (strict && !this._fullWeekdaysParse[i]) {
1725            this._fullWeekdaysParse[i] = new RegExp(
1726                '^' + this.weekdays(mom, '').replace('.', '\\.?') + '$',
1727                'i'
1728            );
1729            this._shortWeekdaysParse[i] = new RegExp(
1730                '^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$',
1731                'i'
1732            );
1733            this._minWeekdaysParse[i] = new RegExp(
1734                '^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$',
1735                'i'
1736            );
1737        }
1738        if (!this._weekdaysParse[i]) {
1739            regex =
1740                '^' +
1741                this.weekdays(mom, '') +
1742                '|^' +
1743                this.weekdaysShort(mom, '') +
1744                '|^' +
1745                this.weekdaysMin(mom, '');
1746            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
1747        }
1748        // test the regex
1749        if (
1750            strict &&
1751            format === 'dddd' &&
1752            this._fullWeekdaysParse[i].test(weekdayName)
1753        ) {
1754            return i;
1755        } else if (
1756            strict &&
1757            format === 'ddd' &&
1758            this._shortWeekdaysParse[i].test(weekdayName)
1759        ) {
1760            return i;
1761        } else if (
1762            strict &&
1763            format === 'dd' &&
1764            this._minWeekdaysParse[i].test(weekdayName)
1765        ) {
1766            return i;
1767        } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
1768            return i;
1769        }
1770    }
1771}
1772
1773// MOMENTS
1774
1775function getSetDayOfWeek(input) {
1776    if (!this.isValid()) {
1777        return input != null ? this : NaN;
1778    }
1779    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
1780    if (input != null) {
1781        input = parseWeekday(input, this.localeData());
1782        return this.add(input - day, 'd');
1783    } else {
1784        return day;
1785    }
1786}
1787
1788function getSetLocaleDayOfWeek(input) {
1789    if (!this.isValid()) {
1790        return input != null ? this : NaN;
1791    }
1792    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
1793    return input == null ? weekday : this.add(input - weekday, 'd');
1794}
1795
1796function getSetISODayOfWeek(input) {
1797    if (!this.isValid()) {
1798        return input != null ? this : NaN;
1799    }
1800
1801    // behaves the same as moment#day except
1802    // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
1803    // as a setter, sunday should belong to the previous week.
1804
1805    if (input != null) {
1806        var weekday = parseIsoWeekday(input, this.localeData());
1807        return this.day(this.day() % 7 ? weekday : weekday - 7);
1808    } else {
1809        return this.day() || 7;
1810    }
1811}
1812
1813function weekdaysRegex(isStrict) {
1814    if (this._weekdaysParseExact) {
1815        if (!hasOwnProp(this, '_weekdaysRegex')) {
1816            computeWeekdaysParse.call(this);
1817        }
1818        if (isStrict) {
1819            return this._weekdaysStrictRegex;
1820        } else {
1821            return this._weekdaysRegex;
1822        }
1823    } else {
1824        if (!hasOwnProp(this, '_weekdaysRegex')) {
1825            this._weekdaysRegex = defaultWeekdaysRegex;
1826        }
1827        return this._weekdaysStrictRegex && isStrict
1828            ? this._weekdaysStrictRegex
1829            : this._weekdaysRegex;
1830    }
1831}
1832
1833function weekdaysShortRegex(isStrict) {
1834    if (this._weekdaysParseExact) {
1835        if (!hasOwnProp(this, '_weekdaysRegex')) {
1836            computeWeekdaysParse.call(this);
1837        }
1838        if (isStrict) {
1839            return this._weekdaysShortStrictRegex;
1840        } else {
1841            return this._weekdaysShortRegex;
1842        }
1843    } else {
1844        if (!hasOwnProp(this, '_weekdaysShortRegex')) {
1845            this._weekdaysShortRegex = defaultWeekdaysShortRegex;
1846        }
1847        return this._weekdaysShortStrictRegex && isStrict
1848            ? this._weekdaysShortStrictRegex
1849            : this._weekdaysShortRegex;
1850    }
1851}
1852
1853function weekdaysMinRegex(isStrict) {
1854    if (this._weekdaysParseExact) {
1855        if (!hasOwnProp(this, '_weekdaysRegex')) {
1856            computeWeekdaysParse.call(this);
1857        }
1858        if (isStrict) {
1859            return this._weekdaysMinStrictRegex;
1860        } else {
1861            return this._weekdaysMinRegex;
1862        }
1863    } else {
1864        if (!hasOwnProp(this, '_weekdaysMinRegex')) {
1865            this._weekdaysMinRegex = defaultWeekdaysMinRegex;
1866        }
1867        return this._weekdaysMinStrictRegex && isStrict
1868            ? this._weekdaysMinStrictRegex
1869            : this._weekdaysMinRegex;
1870    }
1871}
1872
1873function computeWeekdaysParse() {
1874    function cmpLenRev(a, b) {
1875        return b.length - a.length;
1876    }
1877
1878    var minPieces = [],
1879        shortPieces = [],
1880        longPieces = [],
1881        mixedPieces = [],
1882        i,
1883        mom,
1884        minp,
1885        shortp,
1886        longp;
1887    for (i = 0; i < 7; i++) {
1888        // make the regex if we don't have it already
1889        mom = createUTC([2000, 1]).day(i);
1890        minp = regexEscape(this.weekdaysMin(mom, ''));
1891        shortp = regexEscape(this.weekdaysShort(mom, ''));
1892        longp = regexEscape(this.weekdays(mom, ''));
1893        minPieces.push(minp);
1894        shortPieces.push(shortp);
1895        longPieces.push(longp);
1896        mixedPieces.push(minp);
1897        mixedPieces.push(shortp);
1898        mixedPieces.push(longp);
1899    }
1900    // Sorting makes sure if one weekday (or abbr) is a prefix of another it
1901    // will match the longer piece.
1902    minPieces.sort(cmpLenRev);
1903    shortPieces.sort(cmpLenRev);
1904    longPieces.sort(cmpLenRev);
1905    mixedPieces.sort(cmpLenRev);
1906
1907    this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
1908    this._weekdaysShortRegex = this._weekdaysRegex;
1909    this._weekdaysMinRegex = this._weekdaysRegex;
1910
1911    this._weekdaysStrictRegex = new RegExp(
1912        '^(' + longPieces.join('|') + ')',
1913        'i'
1914    );
1915    this._weekdaysShortStrictRegex = new RegExp(
1916        '^(' + shortPieces.join('|') + ')',
1917        'i'
1918    );
1919    this._weekdaysMinStrictRegex = new RegExp(
1920        '^(' + minPieces.join('|') + ')',
1921        'i'
1922    );
1923}
1924
1925// FORMATTING
1926
1927function hFormat() {
1928    return this.hours() % 12 || 12;
1929}
1930
1931function kFormat() {
1932    return this.hours() || 24;
1933}
1934
1935addFormatToken('H', ['HH', 2], 0, 'hour');
1936addFormatToken('h', ['hh', 2], 0, hFormat);
1937addFormatToken('k', ['kk', 2], 0, kFormat);
1938
1939addFormatToken('hmm', 0, 0, function () {
1940    return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
1941});
1942
1943addFormatToken('hmmss', 0, 0, function () {
1944    return (
1945        '' +
1946        hFormat.apply(this) +
1947        zeroFill(this.minutes(), 2) +
1948        zeroFill(this.seconds(), 2)
1949    );
1950});
1951
1952addFormatToken('Hmm', 0, 0, function () {
1953    return '' + this.hours() + zeroFill(this.minutes(), 2);
1954});
1955
1956addFormatToken('Hmmss', 0, 0, function () {
1957    return (
1958        '' +
1959        this.hours() +
1960        zeroFill(this.minutes(), 2) +
1961        zeroFill(this.seconds(), 2)
1962    );
1963});
1964
1965function meridiem(token, lowercase) {
1966    addFormatToken(token, 0, 0, function () {
1967        return this.localeData().meridiem(
1968            this.hours(),
1969            this.minutes(),
1970            lowercase
1971        );
1972    });
1973}
1974
1975meridiem('a', true);
1976meridiem('A', false);
1977
1978// ALIASES
1979
1980addUnitAlias('hour', 'h');
1981
1982// PRIORITY
1983addUnitPriority('hour', 13);
1984
1985// PARSING
1986
1987function matchMeridiem(isStrict, locale) {
1988    return locale._meridiemParse;
1989}
1990
1991addRegexToken('a', matchMeridiem);
1992addRegexToken('A', matchMeridiem);
1993addRegexToken('H', match1to2);
1994addRegexToken('h', match1to2);
1995addRegexToken('k', match1to2);
1996addRegexToken('HH', match1to2, match2);
1997addRegexToken('hh', match1to2, match2);
1998addRegexToken('kk', match1to2, match2);
1999
2000addRegexToken('hmm', match3to4);
2001addRegexToken('hmmss', match5to6);
2002addRegexToken('Hmm', match3to4);
2003addRegexToken('Hmmss', match5to6);
2004
2005addParseToken(['H', 'HH'], HOUR);
2006addParseToken(['k', 'kk'], function (input, array, config) {
2007    var kInput = toInt(input);
2008    array[HOUR] = kInput === 24 ? 0 : kInput;
2009});
2010addParseToken(['a', 'A'], function (input, array, config) {
2011    config._isPm = config._locale.isPM(input);
2012    config._meridiem = input;
2013});
2014addParseToken(['h', 'hh'], function (input, array, config) {
2015    array[HOUR] = toInt(input);
2016    getParsingFlags(config).bigHour = true;
2017});
2018addParseToken('hmm', function (input, array, config) {
2019    var pos = input.length - 2;
2020    array[HOUR] = toInt(input.substr(0, pos));
2021    array[MINUTE] = toInt(input.substr(pos));
2022    getParsingFlags(config).bigHour = true;
2023});
2024addParseToken('hmmss', function (input, array, config) {
2025    var pos1 = input.length - 4,
2026        pos2 = input.length - 2;
2027    array[HOUR] = toInt(input.substr(0, pos1));
2028    array[MINUTE] = toInt(input.substr(pos1, 2));
2029    array[SECOND] = toInt(input.substr(pos2));
2030    getParsingFlags(config).bigHour = true;
2031});
2032addParseToken('Hmm', function (input, array, config) {
2033    var pos = input.length - 2;
2034    array[HOUR] = toInt(input.substr(0, pos));
2035    array[MINUTE] = toInt(input.substr(pos));
2036});
2037addParseToken('Hmmss', function (input, array, config) {
2038    var pos1 = input.length - 4,
2039        pos2 = input.length - 2;
2040    array[HOUR] = toInt(input.substr(0, pos1));
2041    array[MINUTE] = toInt(input.substr(pos1, 2));
2042    array[SECOND] = toInt(input.substr(pos2));
2043});
2044
2045// LOCALES
2046
2047function localeIsPM(input) {
2048    // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
2049    // Using charAt should be more compatible.
2050    return (input + '').toLowerCase().charAt(0) === 'p';
2051}
2052
2053var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i,
2054    // Setting the hour should keep the time, because the user explicitly
2055    // specified which hour they want. So trying to maintain the same hour (in
2056    // a new timezone) makes sense. Adding/subtracting hours does not follow
2057    // this rule.
2058    getSetHour = makeGetSet('Hours', true);
2059
2060function localeMeridiem(hours, minutes, isLower) {
2061    if (hours > 11) {
2062        return isLower ? 'pm' : 'PM';
2063    } else {
2064        return isLower ? 'am' : 'AM';
2065    }
2066}
2067
2068var baseConfig = {
2069    calendar: defaultCalendar,
2070    longDateFormat: defaultLongDateFormat,
2071    invalidDate: defaultInvalidDate,
2072    ordinal: defaultOrdinal,
2073    dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
2074    relativeTime: defaultRelativeTime,
2075
2076    months: defaultLocaleMonths,
2077    monthsShort: defaultLocaleMonthsShort,
2078
2079    week: defaultLocaleWeek,
2080
2081    weekdays: defaultLocaleWeekdays,
2082    weekdaysMin: defaultLocaleWeekdaysMin,
2083    weekdaysShort: defaultLocaleWeekdaysShort,
2084
2085    meridiemParse: defaultLocaleMeridiemParse,
2086};
2087
2088// internal storage for locale config files
2089var locales = {},
2090    localeFamilies = {},
2091    globalLocale;
2092
2093function commonPrefix(arr1, arr2) {
2094    var i,
2095        minl = Math.min(arr1.length, arr2.length);
2096    for (i = 0; i < minl; i += 1) {
2097        if (arr1[i] !== arr2[i]) {
2098            return i;
2099        }
2100    }
2101    return minl;
2102}
2103
2104function normalizeLocale(key) {
2105    return key ? key.toLowerCase().replace('_', '-') : key;
2106}
2107
2108// pick the locale from the array
2109// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
2110// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
2111function chooseLocale(names) {
2112    var i = 0,
2113        j,
2114        next,
2115        locale,
2116        split;
2117
2118    while (i < names.length) {
2119        split = normalizeLocale(names[i]).split('-');
2120        j = split.length;
2121        next = normalizeLocale(names[i + 1]);
2122        next = next ? next.split('-') : null;
2123        while (j > 0) {
2124            locale = loadLocale(split.slice(0, j).join('-'));
2125            if (locale) {
2126                return locale;
2127            }
2128            if (
2129                next &&
2130                next.length >= j &&
2131                commonPrefix(split, next) >= j - 1
2132            ) {
2133                //the next array item is better than a shallower substring of this one
2134                break;
2135            }
2136            j--;
2137        }
2138        i++;
2139    }
2140    return globalLocale;
2141}
2142
2143function 
vendor: 9,742 bytes, lines 2143-2440
2143loadLocale(name) {
2144    var oldLocale = null,
2145        aliasedRequire;
2146    // TODO: Find a better way to register and load all the locales in Node
2147    if (
2148        locales[name] === undefined &&
2149        typeof module !== 'undefined' &&
2150        module &&
2151        module.exports
2152    ) {
2153        try {
2154            oldLocale = globalLocale._abbr;
2155            aliasedRequire = require;
2156            __webpack_require__(161)("./" + name);
2157            getSetGlobalLocale(oldLocale);
2158        } catch (e) {
2159            // mark as not found to avoid repeating expensive file require call causing high CPU
2160            // when trying to find en-US, en_US, en-us for every format call
2161            locales[name] = null; // null means not found
2162        }
2163    }
2164    return locales[name];
2165}
2166
2167// This function will load locale and then set the global locale.  If
2168// no arguments are passed in, it will simply return the current global
2169// locale key.
2170function getSetGlobalLocale(key, values) {
2171    var data;
2172    if (key) {
2173        if (isUndefined(values)) {
2174            data = getLocale(key);
2175        } else {
2176            data = defineLocale(key, values);
2177        }
2178
2179        if (data) {
2180            // moment.duration._locale = moment._locale = data;
2181            globalLocale = data;
2182        } else {
2183            if (typeof console !== 'undefined' && console.warn) {
2184                //warn user if arguments are passed but the locale could not be set
2185                console.warn(
2186                    'Locale ' + key + ' not found. Did you forget to load it?'
2187                );
2188            }
2189        }
2190    }
2191
2192    return globalLocale._abbr;
2193}
2194
2195function defineLocale(name, config) {
2196    if (config !== null) {
2197        var locale,
2198            parentConfig = baseConfig;
2199        config.abbr = name;
2200        if (locales[name] != null) {
2201            deprecateSimple(
2202                'defineLocaleOverride',
2203                'use moment.updateLocale(localeName, config) to change ' +
2204                    'an existing locale. moment.defineLocale(localeName, ' +
2205                    'config) should only be used for creating a new locale ' +
2206                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'
2207            );
2208            parentConfig = locales[name]._config;
2209        } else if (config.parentLocale != null) {
2210            if (locales[config.parentLocale] != null) {
2211                parentConfig = locales[config.parentLocale]._config;
2212            } else {
2213                locale = loadLocale(config.parentLocale);
2214                if (locale != null) {
2215                    parentConfig = locale._config;
2216                } else {
2217                    if (!localeFamilies[config.parentLocale]) {
2218                        localeFamilies[config.parentLocale] = [];
2219                    }
2220                    localeFamilies[config.parentLocale].push({
2221                        name: name,
2222                        config: config,
2223                    });
2224                    return null;
2225                }
2226            }
2227        }
2228        locales[name] = new Locale(mergeConfigs(parentConfig, config));
2229
2230        if (localeFamilies[name]) {
2231            localeFamilies[name].forEach(function (x) {
2232                defineLocale(x.name, x.config);
2233            });
2234        }
2235
2236        // backwards compat for now: also set the locale
2237        // make sure we set the locale AFTER all child locales have been
2238        // created, so we won't end up with the child locale set.
2239        getSetGlobalLocale(name);
2240
2241        return locales[name];
2242    } else {
2243        // useful for testing
2244        delete locales[name];
2245        return null;
2246    }
2247}
2248
2249function updateLocale(name, config) {
2250    if (config != null) {
2251        var locale,
2252            tmpLocale,
2253            parentConfig = baseConfig;
2254
2255        if (locales[name] != null && locales[name].parentLocale != null) {
2256            // Update existing child locale in-place to avoid memory-leaks
2257            locales[name].set(mergeConfigs(locales[name]._config, config));
2258        } else {
2259            // MERGE
2260            tmpLocale = loadLocale(name);
2261            if (tmpLocale != null) {
2262                parentConfig = tmpLocale._config;
2263            }
2264            config = mergeConfigs(parentConfig, config);
2265            if (tmpLocale == null) {
2266                // updateLocale is called for creating a new locale
2267                // Set abbr so it will have a name (getters return
2268                // undefined otherwise).
2269                config.abbr = name;
2270            }
2271            locale = new Locale(config);
2272            locale.parentLocale = locales[name];
2273            locales[name] = locale;
2274        }
2275
2276        // backwards compat for now: also set the locale
2277        getSetGlobalLocale(name);
2278    } else {
2279        // pass null for config to unupdate, useful for tests
2280        if (locales[name] != null) {
2281            if (locales[name].parentLocale != null) {
2282                locales[name] = locales[name].parentLocale;
2283                if (name === getSetGlobalLocale()) {
2284                    getSetGlobalLocale(name);
2285                }
2286            } else if (locales[name] != null) {
2287                delete locales[name];
2288            }
2289        }
2290    }
2291    return locales[name];
2292}
2293
2294// returns locale data
2295function getLocale(key) {
2296    var locale;
2297
2298    if (key && key._locale && key._locale._abbr) {
2299        key = key._locale._abbr;
2300    }
2301
2302    if (!key) {
2303        return globalLocale;
2304    }
2305
2306    if (!isArray(key)) {
2307        //short-circuit everything else
2308        locale = loadLocale(key);
2309        if (locale) {
2310            return locale;
2311        }
2312        key = [key];
2313    }
2314
2315    return chooseLocale(key);
2316}
2317
2318function listLocales() {
2319    return keys(locales);
2320}
2321
2322function checkOverflow(m) {
2323    var overflow,
2324        a = m._a;
2325
2326    if (a && getParsingFlags(m).overflow === -2) {
2327        overflow =
2328            a[MONTH] < 0 || a[MONTH] > 11
2329                ? MONTH
2330                : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH])
2331                ? DATE
2332                : a[HOUR] < 0 ||
2333                  a[HOUR] > 24 ||
2334                  (a[HOUR] === 24 &&
2335                      (a[MINUTE] !== 0 ||
2336                          a[SECOND] !== 0 ||
2337                          a[MILLISECOND] !== 0))
2338                ? HOUR
2339                : a[MINUTE] < 0 || a[MINUTE] > 59
2340                ? MINUTE
2341                : a[SECOND] < 0 || a[SECOND] > 59
2342                ? SECOND
2343                : a[MILLISECOND] < 0 || a[MILLISECOND] > 999
2344                ? MILLISECOND
2345                : -1;
2346
2347        if (
2348            getParsingFlags(m)._overflowDayOfYear &&
2349            (overflow < YEAR || overflow > DATE)
2350        ) {
2351            overflow = DATE;
2352        }
2353        if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
2354            overflow = WEEK;
2355        }
2356        if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
2357            overflow = WEEKDAY;
2358        }
2359
2360        getParsingFlags(m).overflow = overflow;
2361    }
2362
2363    return m;
2364}
2365
2366// iso 8601 regex
2367// 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)
2368var 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)?)?$/,
2369    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)?)?$/,
2370    tzRegex = /Z|[+-]\d\d(?::?\d\d)?/,
2371    isoDates = [
2372        ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
2373        ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
2374        ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
2375        ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
2376        ['YYYY-DDD', /\d{4}-\d{3}/],
2377        ['YYYY-MM', /\d{4}-\d\d/, false],
2378        ['YYYYYYMMDD', /[+-]\d{10}/],
2379        ['YYYYMMDD', /\d{8}/],
2380        ['GGGG[W]WWE', /\d{4}W\d{3}/],
2381        ['GGGG[W]WW', /\d{4}W\d{2}/, false],
2382        ['YYYYDDD', /\d{7}/],
2383        ['YYYYMM', /\d{6}/, false],
2384        ['YYYY', /\d{4}/, false],
2385    ],
2386    // iso time formats and regexes
2387    isoTimes = [
2388        ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
2389        ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
2390        ['HH:mm:ss', /\d\d:\d\d:\d\d/],
2391        ['HH:mm', /\d\d:\d\d/],
2392        ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
2393        ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
2394        ['HHmmss', /\d\d\d\d\d\d/],
2395        ['HHmm', /\d\d\d\d/],
2396        ['HH', /\d\d/],
2397    ],
2398    aspNetJsonRegex = /^\/?Date\((-?\d+)/i,
2399    // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
2400    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}))$/,
2401    obsOffsets = {
2402        UT: 0,
2403        GMT: 0,
2404        EDT: -4 * 60,
2405        EST: -5 * 60,
2406        CDT: -5 * 60,
2407        CST: -6 * 60,
2408        MDT: -6 * 60,
2409        MST: -7 * 60,
2410        PDT: -7 * 60,
2411        PST: -8 * 60,
2412    };
2413
2414// date from iso format
2415function configFromISO(config) {
2416    var i,
2417        l,
2418        string = config._i,
2419        match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
2420        allowTime,
2421        dateFormat,
2422        timeFormat,
2423        tzFormat;
2424
2425    if (match) {
2426        getParsingFlags(config).iso = true;
2427
2428        for (i = 0, l = isoDates.length; i < l; i++) {
2429            if (isoDates[i][1].exec(match[1])) {
2430                dateFormat = isoDates[i][0];
2431                allowTime = isoDates[i][2] !== false;
2432                break;
2433            }
2434        }
2435        if (dateFormat == null) {
2436            config._isValid = false;
2437            return;
2438        }
2439        if (match[3]) {
2440            for (i = 0, l = isoTimes.length
vendor: 10,877 bytes, lines 2440-2820
2440; i < l; i++) {
2441                if (isoTimes[i][1].exec(match[3])) {
2442                    // match[2] should be 'T' or space
2443                    timeFormat = (match[2] || ' ') + isoTimes[i][0];
2444                    break;
2445                }
2446            }
2447            if (timeFormat == null) {
2448                config._isValid = false;
2449                return;
2450            }
2451        }
2452        if (!allowTime && timeFormat != null) {
2453            config._isValid = false;
2454            return;
2455        }
2456        if (match[4]) {
2457            if (tzRegex.exec(match[4])) {
2458                tzFormat = 'Z';
2459            } else {
2460                config._isValid = false;
2461                return;
2462            }
2463        }
2464        config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
2465        configFromStringAndFormat(config);
2466    } else {
2467        config._isValid = false;
2468    }
2469}
2470
2471function extractFromRFC2822Strings(
2472    yearStr,
2473    monthStr,
2474    dayStr,
2475    hourStr,
2476    minuteStr,
2477    secondStr
2478) {
2479    var result = [
2480        untruncateYear(yearStr),
2481        defaultLocaleMonthsShort.indexOf(monthStr),
2482        parseInt(dayStr, 10),
2483        parseInt(hourStr, 10),
2484        parseInt(minuteStr, 10),
2485    ];
2486
2487    if (secondStr) {
2488        result.push(parseInt(secondStr, 10));
2489    }
2490
2491    return result;
2492}
2493
2494function untruncateYear(yearStr) {
2495    var year = parseInt(yearStr, 10);
2496    if (year <= 49) {
2497        return 2000 + year;
2498    } else if (year <= 999) {
2499        return 1900 + year;
2500    }
2501    return year;
2502}
2503
2504function preprocessRFC2822(s) {
2505    // Remove comments and folding whitespace and replace multiple-spaces with a single space
2506    return s
2507        .replace(/\([^)]*\)|[\n\t]/g, ' ')
2508        .replace(/(\s\s+)/g, ' ')
2509        .replace(/^\s\s*/, '')
2510        .replace(/\s\s*$/, '');
2511}
2512
2513function checkWeekday(weekdayStr, parsedInput, config) {
2514    if (weekdayStr) {
2515        // TODO: Replace the vanilla JS Date object with an independent day-of-week check.
2516        var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
2517            weekdayActual = new Date(
2518                parsedInput[0],
2519                parsedInput[1],
2520                parsedInput[2]
2521            ).getDay();
2522        if (weekdayProvided !== weekdayActual) {
2523            getParsingFlags(config).weekdayMismatch = true;
2524            config._isValid = false;
2525            return false;
2526        }
2527    }
2528    return true;
2529}
2530
2531function calculateOffset(obsOffset, militaryOffset, numOffset) {
2532    if (obsOffset) {
2533        return obsOffsets[obsOffset];
2534    } else if (militaryOffset) {
2535        // the only allowed military tz is Z
2536        return 0;
2537    } else {
2538        var hm = parseInt(numOffset, 10),
2539            m = hm % 100,
2540            h = (hm - m) / 100;
2541        return h * 60 + m;
2542    }
2543}
2544
2545// date and time from ref 2822 format
2546function configFromRFC2822(config) {
2547    var match = rfc2822.exec(preprocessRFC2822(config._i)),
2548        parsedArray;
2549    if (match) {
2550        parsedArray = extractFromRFC2822Strings(
2551            match[4],
2552            match[3],
2553            match[2],
2554            match[5],
2555            match[6],
2556            match[7]
2557        );
2558        if (!checkWeekday(match[1], parsedArray, config)) {
2559            return;
2560        }
2561
2562        config._a = parsedArray;
2563        config._tzm = calculateOffset(match[8], match[9], match[10]);
2564
2565        config._d = createUTCDate.apply(null, config._a);
2566        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
2567
2568        getParsingFlags(config).rfc2822 = true;
2569    } else {
2570        config._isValid = false;
2571    }
2572}
2573
2574// date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict
2575function configFromString(config) {
2576    var matched = aspNetJsonRegex.exec(config._i);
2577    if (matched !== null) {
2578        config._d = new Date(+matched[1]);
2579        return;
2580    }
2581
2582    configFromISO(config);
2583    if (config._isValid === false) {
2584        delete config._isValid;
2585    } else {
2586        return;
2587    }
2588
2589    configFromRFC2822(config);
2590    if (config._isValid === false) {
2591        delete config._isValid;
2592    } else {
2593        return;
2594    }
2595
2596    if (config._strict) {
2597        config._isValid = false;
2598    } else {
2599        // Final attempt, use Input Fallback
2600        hooks.createFromInputFallback(config);
2601    }
2602}
2603
2604hooks.createFromInputFallback = deprecate(
2605    'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
2606        'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
2607        'discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.',
2608    function (config) {
2609        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
2610    }
2611);
2612
2613// Pick the first defined of two or three arguments.
2614function defaults(a, b, c) {
2615    if (a != null) {
2616        return a;
2617    }
2618    if (b != null) {
2619        return b;
2620    }
2621    return c;
2622}
2623
2624function currentDateArray(config) {
2625    // hooks is actually the exported moment object
2626    var nowValue = new Date(hooks.now());
2627    if (config._useUTC) {
2628        return [
2629            nowValue.getUTCFullYear(),
2630            nowValue.getUTCMonth(),
2631            nowValue.getUTCDate(),
2632        ];
2633    }
2634    return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
2635}
2636
2637// convert an array to a date.
2638// the array should mirror the parameters below
2639// note: all values past the year are optional and will default to the lowest possible value.
2640// [year, month, day , hour, minute, second, millisecond]
2641function configFromArray(config) {
2642    var i,
2643        date,
2644        input = [],
2645        currentDate,
2646        expectedWeekday,
2647        yearToUse;
2648
2649    if (config._d) {
2650        return;
2651    }
2652
2653    currentDate = currentDateArray(config);
2654
2655    //compute day of the year from weeks and weekdays
2656    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
2657        dayOfYearFromWeekInfo(config);
2658    }
2659
2660    //if the day of the year is set, figure out what it is
2661    if (config._dayOfYear != null) {
2662        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
2663
2664        if (
2665            config._dayOfYear > daysInYear(yearToUse) ||
2666            config._dayOfYear === 0
2667        ) {
2668            getParsingFlags(config)._overflowDayOfYear = true;
2669        }
2670
2671        date = createUTCDate(yearToUse, 0, config._dayOfYear);
2672        config._a[MONTH] = date.getUTCMonth();
2673        config._a[DATE] = date.getUTCDate();
2674    }
2675
2676    // Default to current date.
2677    // * if no year, month, day of month are given, default to today
2678    // * if day of month is given, default month and year
2679    // * if month is given, default only year
2680    // * if year is given, don't default anything
2681    for (i = 0; i < 3 && config._a[i] == null; ++i) {
2682        config._a[i] = input[i] = currentDate[i];
2683    }
2684
2685    // Zero out whatever was not defaulted, including time
2686    for (; i < 7; i++) {
2687        config._a[i] = input[i] =
2688            config._a[i] == null ? (i === 2 ? 1 : 0) : config._a[i];
2689    }
2690
2691    // Check for 24:00:00.000
2692    if (
2693        config._a[HOUR] === 24 &&
2694        config._a[MINUTE] === 0 &&
2695        config._a[SECOND] === 0 &&
2696        config._a[MILLISECOND] === 0
2697    ) {
2698        config._nextDay = true;
2699        config._a[HOUR] = 0;
2700    }
2701
2702    config._d = (config._useUTC ? createUTCDate : createDate).apply(
2703        null,
2704        input
2705    );
2706    expectedWeekday = config._useUTC
2707        ? config._d.getUTCDay()
2708        : config._d.getDay();
2709
2710    // Apply timezone offset from input. The actual utcOffset can be changed
2711    // with parseZone.
2712    if (config._tzm != null) {
2713        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
2714    }
2715
2716    if (config._nextDay) {
2717        config._a[HOUR] = 24;
2718    }
2719
2720    // check for mismatching day of week
2721    if (
2722        config._w &&
2723        typeof config._w.d !== 'undefined' &&
2724        config._w.d !== expectedWeekday
2725    ) {
2726        getParsingFlags(config).weekdayMismatch = true;
2727    }
2728}
2729
2730function dayOfYearFromWeekInfo(config) {
2731    var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek;
2732
2733    w = config._w;
2734    if (w.GG != null || w.W != null || w.E != null) {
2735        dow = 1;
2736        doy = 4;
2737
2738        // TODO: We need to take the current isoWeekYear, but that depends on
2739        // how we interpret now (local, utc, fixed offset). So create
2740        // a now version of current config (take local/utc/offset flags, and
2741        // create now).
2742        weekYear = defaults(
2743            w.GG,
2744            config._a[YEAR],
2745            weekOfYear(createLocal(), 1, 4).year
2746        );
2747        week = defaults(w.W, 1);
2748        weekday = defaults(w.E, 1);
2749        if (weekday < 1 || weekday > 7) {
2750            weekdayOverflow = true;
2751        }
2752    } else {
2753        dow = config._locale._week.dow;
2754        doy = config._locale._week.doy;
2755
2756        curWeek = weekOfYear(createLocal(), dow, doy);
2757
2758        weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
2759
2760        // Default to current week.
2761        week = defaults(w.w, curWeek.week);
2762
2763        if (w.d != null) {
2764            // weekday -- low day numbers are considered next week
2765            weekday = w.d;
2766            if (weekday < 0 || weekday > 6) {
2767                weekdayOverflow = true;
2768            }
2769        } else if (w.e != null) {
2770            // local weekday -- counting starts from beginning of week
2771            weekday = w.e + dow;
2772            if (w.e < 0 || w.e > 6) {
2773                weekdayOverflow = true;
2774            }
2775        } else {
2776            // default to beginning of week
2777            weekday = dow;
2778        }
2779    }
2780    if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
2781        getParsingFlags(config)._overflowWeeks = true;
2782    } else if (weekdayOverflow != null) {
2783        getParsingFlags(config)._overflowWeekday = true;
2784    } else {
2785        temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
2786        config._a[YEAR] = temp.year;
2787        config._dayOfYear = temp.dayOfYear;
2788    }
2789}
2790
2791// constant that refers to the ISO standard
2792hooks.ISO_8601 = function () {};
2793
2794// constant that refers to the RFC 2822 form
2795hooks.RFC_2822 = function () {};
2796
2797// date from string and format string
2798function configFromStringAndFormat(config) {
2799    // TODO: Move this to another part of the creation flow to prevent circular deps
2800    if (config._f === hooks.ISO_8601) {
2801        configFromISO(config);
2802        return;
2803    }
2804    if (config._f === hooks.RFC_2822) {
2805        configFromRFC2822(config);
2806        return;
2807    }
2808    config._a = [];
2809    getParsingFlags(config).empty = true;
2810
2811    // This array is used to make a Date, either with `new Date` or `Date.UTC`
2812    var string = '' + config._i,
2813        i,
2814        parsedInput,
2815        tokens,
2816        token,
2817        skipped,
2818        stringLength = string.length,
2819        totalParsedInputLength = 0,
2820        era
vendor: 14,811 bytes, lines 2820-3360
2820;
2821
2822    tokens =
2823        expandFormat(config._f, config._locale).match(formattingTokens) || [];
2824
2825    for (i = 0; i < tokens.length; i++) {
2826        token = tokens[i];
2827        parsedInput = (string.match(getParseRegexForToken(token, config)) ||
2828            [])[0];
2829        if (parsedInput) {
2830            skipped = string.substr(0, string.indexOf(parsedInput));
2831            if (skipped.length > 0) {
2832                getParsingFlags(config).unusedInput.push(skipped);
2833            }
2834            string = string.slice(
2835                string.indexOf(parsedInput) + parsedInput.length
2836            );
2837            totalParsedInputLength += parsedInput.length;
2838        }
2839        // don't parse if it's not a known token
2840        if (formatTokenFunctions[token]) {
2841            if (parsedInput) {
2842                getParsingFlags(config).empty = false;
2843            } else {
2844                getParsingFlags(config).unusedTokens.push(token);
2845            }
2846            addTimeToArrayFromToken(token, parsedInput, config);
2847        } else if (config._strict && !parsedInput) {
2848            getParsingFlags(config).unusedTokens.push(token);
2849        }
2850    }
2851
2852    // add remaining unparsed input length to the string
2853    getParsingFlags(config).charsLeftOver =
2854        stringLength - totalParsedInputLength;
2855    if (string.length > 0) {
2856        getParsingFlags(config).unusedInput.push(string);
2857    }
2858
2859    // clear _12h flag if hour is <= 12
2860    if (
2861        config._a[HOUR] <= 12 &&
2862        getParsingFlags(config).bigHour === true &&
2863        config._a[HOUR] > 0
2864    ) {
2865        getParsingFlags(config).bigHour = undefined;
2866    }
2867
2868    getParsingFlags(config).parsedDateParts = config._a.slice(0);
2869    getParsingFlags(config).meridiem = config._meridiem;
2870    // handle meridiem
2871    config._a[HOUR] = meridiemFixWrap(
2872        config._locale,
2873        config._a[HOUR],
2874        config._meridiem
2875    );
2876
2877    // handle era
2878    era = getParsingFlags(config).era;
2879    if (era !== null) {
2880        config._a[YEAR] = config._locale.erasConvertYear(era, config._a[YEAR]);
2881    }
2882
2883    configFromArray(config);
2884    checkOverflow(config);
2885}
2886
2887function meridiemFixWrap(locale, hour, meridiem) {
2888    var isPm;
2889
2890    if (meridiem == null) {
2891        // nothing to do
2892        return hour;
2893    }
2894    if (locale.meridiemHour != null) {
2895        return locale.meridiemHour(hour, meridiem);
2896    } else if (locale.isPM != null) {
2897        // Fallback
2898        isPm = locale.isPM(meridiem);
2899        if (isPm && hour < 12) {
2900            hour += 12;
2901        }
2902        if (!isPm && hour === 12) {
2903            hour = 0;
2904        }
2905        return hour;
2906    } else {
2907        // this is not supposed to happen
2908        return hour;
2909    }
2910}
2911
2912// date from string and array of format strings
2913function configFromStringAndArray(config) {
2914    var tempConfig,
2915        bestMoment,
2916        scoreToBeat,
2917        i,
2918        currentScore,
2919        validFormatFound,
2920        bestFormatIsValid = false;
2921
2922    if (config._f.length === 0) {
2923        getParsingFlags(config).invalidFormat = true;
2924        config._d = new Date(NaN);
2925        return;
2926    }
2927
2928    for (i = 0; i < config._f.length; i++) {
2929        currentScore = 0;
2930        validFormatFound = false;
2931        tempConfig = copyConfig({}, config);
2932        if (config._useUTC != null) {
2933            tempConfig._useUTC = config._useUTC;
2934        }
2935        tempConfig._f = config._f[i];
2936        configFromStringAndFormat(tempConfig);
2937
2938        if (isValid(tempConfig)) {
2939            validFormatFound = true;
2940        }
2941
2942        // if there is any input that was not parsed add a penalty for that format
2943        currentScore += getParsingFlags(tempConfig).charsLeftOver;
2944
2945        //or tokens
2946        currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
2947
2948        getParsingFlags(tempConfig).score = currentScore;
2949
2950        if (!bestFormatIsValid) {
2951            if (
2952                scoreToBeat == null ||
2953                currentScore < scoreToBeat ||
2954                validFormatFound
2955            ) {
2956                scoreToBeat = currentScore;
2957                bestMoment = tempConfig;
2958                if (validFormatFound) {
2959                    bestFormatIsValid = true;
2960                }
2961            }
2962        } else {
2963            if (currentScore < scoreToBeat) {
2964                scoreToBeat = currentScore;
2965                bestMoment = tempConfig;
2966            }
2967        }
2968    }
2969
2970    extend(config, bestMoment || tempConfig);
2971}
2972
2973function configFromObject(config) {
2974    if (config._d) {
2975        return;
2976    }
2977
2978    var i = normalizeObjectUnits(config._i),
2979        dayOrDate = i.day === undefined ? i.date : i.day;
2980    config._a = map(
2981        [i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond],
2982        function (obj) {
2983            return obj && parseInt(obj, 10);
2984        }
2985    );
2986
2987    configFromArray(config);
2988}
2989
2990function createFromConfig(config) {
2991    var res = new Moment(checkOverflow(prepareConfig(config)));
2992    if (res._nextDay) {
2993        // Adding is smart enough around DST
2994        res.add(1, 'd');
2995        res._nextDay = undefined;
2996    }
2997
2998    return res;
2999}
3000
3001function prepareConfig(config) {
3002    var input = config._i,
3003        format = config._f;
3004
3005    config._locale = config._locale || getLocale(config._l);
3006
3007    if (input === null || (format === undefined && input === '')) {
3008        return createInvalid({ nullInput: true });
3009    }
3010
3011    if (typeof input === 'string') {
3012        config._i = input = config._locale.preparse(input);
3013    }
3014
3015    if (isMoment(input)) {
3016        return new Moment(checkOverflow(input));
3017    } else if (isDate(input)) {
3018        config._d = input;
3019    } else if (isArray(format)) {
3020        configFromStringAndArray(config);
3021    } else if (format) {
3022        configFromStringAndFormat(config);
3023    } else {
3024        configFromInput(config);
3025    }
3026
3027    if (!isValid(config)) {
3028        config._d = null;
3029    }
3030
3031    return config;
3032}
3033
3034function configFromInput(config) {
3035    var input = config._i;
3036    if (isUndefined(input)) {
3037        config._d = new Date(hooks.now());
3038    } else if (isDate(input)) {
3039        config._d = new Date(input.valueOf());
3040    } else if (typeof input === 'string') {
3041        configFromString(config);
3042    } else if (isArray(input)) {
3043        config._a = map(input.slice(0), function (obj) {
3044            return parseInt(obj, 10);
3045        });
3046        configFromArray(config);
3047    } else if (isObject(input)) {
3048        configFromObject(config);
3049    } else if (isNumber(input)) {
3050        // from milliseconds
3051        config._d = new Date(input);
3052    } else {
3053        hooks.createFromInputFallback(config);
3054    }
3055}
3056
3057function createLocalOrUTC(input, format, locale, strict, isUTC) {
3058    var c = {};
3059
3060    if (format === true || format === false) {
3061        strict = format;
3062        format = undefined;
3063    }
3064
3065    if (locale === true || locale === false) {
3066        strict = locale;
3067        locale = undefined;
3068    }
3069
3070    if (
3071        (isObject(input) && isObjectEmpty(input)) ||
3072        (isArray(input) && input.length === 0)
3073    ) {
3074        input = undefined;
3075    }
3076    // object construction must be done this way.
3077    // https://github.com/moment/moment/issues/1423
3078    c._isAMomentObject = true;
3079    c._useUTC = c._isUTC = isUTC;
3080    c._l = locale;
3081    c._i = input;
3082    c._f = format;
3083    c._strict = strict;
3084
3085    return createFromConfig(c);
3086}
3087
3088function createLocal(input, format, locale, strict) {
3089    return createLocalOrUTC(input, format, locale, strict, false);
3090}
3091
3092var prototypeMin = deprecate(
3093        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
3094        function () {
3095            var other = createLocal.apply(null, arguments);
3096            if (this.isValid() && other.isValid()) {
3097                return other < this ? this : other;
3098            } else {
3099                return createInvalid();
3100            }
3101        }
3102    ),
3103    prototypeMax = deprecate(
3104        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
3105        function () {
3106            var other = createLocal.apply(null, arguments);
3107            if (this.isValid() && other.isValid()) {
3108                return other > this ? this : other;
3109            } else {
3110                return createInvalid();
3111            }
3112        }
3113    );
3114
3115// Pick a moment m from moments so that m[fn](other) is true for all
3116// other. This relies on the function fn to be transitive.
3117//
3118// moments should either be an array of moment objects or an array, whose
3119// first element is an array of moment objects.
3120function pickBy(fn, moments) {
3121    var res, i;
3122    if (moments.length === 1 && isArray(moments[0])) {
3123        moments = moments[0];
3124    }
3125    if (!moments.length) {
3126        return createLocal();
3127    }
3128    res = moments[0];
3129    for (i = 1; i < moments.length; ++i) {
3130        if (!moments[i].isValid() || moments[i][fn](res)) {
3131            res = moments[i];
3132        }
3133    }
3134    return res;
3135}
3136
3137// TODO: Use [].sort instead?
3138function min() {
3139    var args = [].slice.call(arguments, 0);
3140
3141    return pickBy('isBefore', args);
3142}
3143
3144function max() {
3145    var args = [].slice.call(arguments, 0);
3146
3147    return pickBy('isAfter', args);
3148}
3149
3150var now = function () {
3151    return Date.now ? Date.now() : +new Date();
3152};
3153
3154var ordering = [
3155    'year',
3156    'quarter',
3157    'month',
3158    'week',
3159    'day',
3160    'hour',
3161    'minute',
3162    'second',
3163    'millisecond',
3164];
3165
3166function isDurationValid(m) {
3167    var key,
3168        unitHasDecimal = false,
3169        i;
3170    for (key in m) {
3171        if (
3172            hasOwnProp(m, key) &&
3173            !(
3174                indexOf.call(ordering, key) !== -1 &&
3175                (m[key] == null || !isNaN(m[key]))
3176            )
3177        ) {
3178            return false;
3179        }
3180    }
3181
3182    for (i = 0; i < ordering.length; ++i) {
3183        if (m[ordering[i]]) {
3184            if (unitHasDecimal) {
3185                return false; // only allow non-integers for smallest unit
3186            }
3187            if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
3188                unitHasDecimal = true;
3189            }
3190        }
3191    }
3192
3193    return true;
3194}
3195
3196function isValid$1() {
3197    return this._isValid;
3198}
3199
3200function createInvalid$1() {
3201    return createDuration(NaN);
3202}
3203
3204function Duration(duration) {
3205    var normalizedInput = normalizeObjectUnits(duration),
3206        years = normalizedInput.year || 0,
3207        quarters = normalizedInput.quarter || 0,
3208        months = normalizedInput.month || 0,
3209        weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
3210        days = normalizedInput.day || 0,
3211        hours = normalizedInput.hour || 0,
3212        minutes = normalizedInput.minute || 0,
3213        seconds = normalizedInput.second || 0,
3214        milliseconds = normalizedInput.millisecond || 0;
3215
3216    this._isValid = isDurationValid(normalizedInput);
3217
3218    // representation for dateAddRemove
3219    this._milliseconds =
3220        +milliseconds +
3221        seconds * 1e3 + // 1000
3222        minutes * 6e4 + // 1000 * 60
3223        hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
3224    // Because of dateAddRemove treats 24 hours as different from a
3225    // day when working around DST, we need to store them separately
3226    this._days = +days + weeks * 7;
3227    // It is impossible to translate months into days without knowing
3228    // which months you are are talking about, so we have to store
3229    // it separately.
3230    this._months = +months + quarters * 3 + years * 12;
3231
3232    this._data = {};
3233
3234    this._locale = getLocale();
3235
3236    this._bubble();
3237}
3238
3239function isDuration(obj) {
3240    return obj instanceof Duration;
3241}
3242
3243function absRound(number) {
3244    if (number < 0) {
3245        return Math.round(-1 * number) * -1;
3246    } else {
3247        return Math.round(number);
3248    }
3249}
3250
3251// compare two arrays, return the number of differences
3252function compareArrays(array1, array2, dontConvert) {
3253    var len = Math.min(array1.length, array2.length),
3254        lengthDiff = Math.abs(array1.length - array2.length),
3255        diffs = 0,
3256        i;
3257    for (i = 0; i < len; i++) {
3258        if (
3259            (dontConvert && array1[i] !== array2[i]) ||
3260            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))
3261        ) {
3262            diffs++;
3263        }
3264    }
3265    return diffs + lengthDiff;
3266}
3267
3268// FORMATTING
3269
3270function offset(token, separator) {
3271    addFormatToken(token, 0, 0, function () {
3272        var offset = this.utcOffset(),
3273            sign = '+';
3274        if (offset < 0) {
3275            offset = -offset;
3276            sign = '-';
3277        }
3278        return (
3279            sign +
3280            zeroFill(~~(offset / 60), 2) +
3281            separator +
3282            zeroFill(~~offset % 60, 2)
3283        );
3284    });
3285}
3286
3287offset('Z', ':');
3288offset('ZZ', '');
3289
3290// PARSING
3291
3292addRegexToken('Z', matchShortOffset);
3293addRegexToken('ZZ', matchShortOffset);
3294addParseToken(['Z', 'ZZ'], function (input, array, config) {
3295    config._useUTC = true;
3296    config._tzm = offsetFromString(matchShortOffset, input);
3297});
3298
3299// HELPERS
3300
3301// timezone chunker
3302// '+10:00' > ['10',  '00']
3303// '-1530'  > ['-15', '30']
3304var chunkOffset = /([\+\-]|\d\d)/gi;
3305
3306function offsetFromString(matcher, string) {
3307    var matches = (string || '').match(matcher),
3308        chunk,
3309        parts,
3310        minutes;
3311
3312    if (matches === null) {
3313        return null;
3314    }
3315
3316    chunk = matches[matches.length - 1] || [];
3317    parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
3318    minutes = +(parts[1] * 60) + toInt(parts[2]);
3319
3320    return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
3321}
3322
3323// Return a moment from input, that is local/utc/zone equivalent to model.
3324function cloneWithOffset(input, model) {
3325    var res, diff;
3326    if (model._isUTC) {
3327        res = model.clone();
3328        diff =
3329            (isMoment(input) || isDate(input)
3330                ? input.valueOf()
3331                : createLocal(input).valueOf()) - res.valueOf();
3332        // Use low-level api, because this fn is low-level api.
3333        res._d.setTime(res._d.valueOf() + diff);
3334        hooks.updateOffset(res, false);
3335        return res;
3336    } else {
3337        return createLocal(input).local();
3338    }
3339}
3340
3341function getDateOffset(m) {
3342    // On Firefox.24 Date#getTimezoneOffset returns a floating point.
3343    // https://github.com/moment/moment/pull/1871
3344    return -Math.round(m._d.getTimezoneOffset());
3345}
3346
3347// HOOKS
3348
3349// This function will be called whenever a moment is mutated.
3350// It is intended to keep the offset in sync with the timezone.
3351hooks.updateOffset = function () {};
3352
3353// MOMENTS
3354
3355// keepLocalTime = true means only change the timezone, without
3356// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
3357// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
3358// +0200, so we adjust the time as needed, to be valid.
3359//
3360// Keeping the time actually adds/subtracts (one hour)
vendor: 10,380 bytes, lines 3361-3730
3361// from the actual represented time. That is why we call updateOffset
3362// a second time. In case it wants us to change the offset again
3363// _changeInProgress == true case, then we have to adjust, because
3364// there is no such time in the given timezone.
3365function getSetOffset(input, keepLocalTime, keepMinutes) {
3366    var offset = this._offset || 0,
3367        localAdjust;
3368    if (!this.isValid()) {
3369        return input != null ? this : NaN;
3370    }
3371    if (input != null) {
3372        if (typeof input === 'string') {
3373            input = offsetFromString(matchShortOffset, input);
3374            if (input === null) {
3375                return this;
3376            }
3377        } else if (Math.abs(input) < 16 && !keepMinutes) {
3378            input = input * 60;
3379        }
3380        if (!this._isUTC && keepLocalTime) {
3381            localAdjust = getDateOffset(this);
3382        }
3383        this._offset = input;
3384        this._isUTC = true;
3385        if (localAdjust != null) {
3386            this.add(localAdjust, 'm');
3387        }
3388        if (offset !== input) {
3389            if (!keepLocalTime || this._changeInProgress) {
3390                addSubtract(
3391                    this,
3392                    createDuration(input - offset, 'm'),
3393                    1,
3394                    false
3395                );
3396            } else if (!this._changeInProgress) {
3397                this._changeInProgress = true;
3398                hooks.updateOffset(this, true);
3399                this._changeInProgress = null;
3400            }
3401        }
3402        return this;
3403    } else {
3404        return this._isUTC ? offset : getDateOffset(this);
3405    }
3406}
3407
3408function getSetZone(input, keepLocalTime) {
3409    if (input != null) {
3410        if (typeof input !== 'string') {
3411            input = -input;
3412        }
3413
3414        this.utcOffset(input, keepLocalTime);
3415
3416        return this;
3417    } else {
3418        return -this.utcOffset();
3419    }
3420}
3421
3422function setOffsetToUTC(keepLocalTime) {
3423    return this.utcOffset(0, keepLocalTime);
3424}
3425
3426function setOffsetToLocal(keepLocalTime) {
3427    if (this._isUTC) {
3428        this.utcOffset(0, keepLocalTime);
3429        this._isUTC = false;
3430
3431        if (keepLocalTime) {
3432            this.subtract(getDateOffset(this), 'm');
3433        }
3434    }
3435    return this;
3436}
3437
3438function setOffsetToParsedOffset() {
3439    if (this._tzm != null) {
3440        this.utcOffset(this._tzm, false, true);
3441    } else if (typeof this._i === 'string') {
3442        var tZone = offsetFromString(matchOffset, this._i);
3443        if (tZone != null) {
3444            this.utcOffset(tZone);
3445        } else {
3446            this.utcOffset(0, true);
3447        }
3448    }
3449    return this;
3450}
3451
3452function hasAlignedHourOffset(input) {
3453    if (!this.isValid()) {
3454        return false;
3455    }
3456    input = input ? createLocal(input).utcOffset() : 0;
3457
3458    return (this.utcOffset() - input) % 60 === 0;
3459}
3460
3461function isDaylightSavingTime() {
3462    return (
3463        this.utcOffset() > this.clone().month(0).utcOffset() ||
3464        this.utcOffset() > this.clone().month(5).utcOffset()
3465    );
3466}
3467
3468function isDaylightSavingTimeShifted() {
3469    if (!isUndefined(this._isDSTShifted)) {
3470        return this._isDSTShifted;
3471    }
3472
3473    var c = {},
3474        other;
3475
3476    copyConfig(c, this);
3477    c = prepareConfig(c);
3478
3479    if (c._a) {
3480        other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
3481        this._isDSTShifted =
3482            this.isValid() && compareArrays(c._a, other.toArray()) > 0;
3483    } else {
3484        this._isDSTShifted = false;
3485    }
3486
3487    return this._isDSTShifted;
3488}
3489
3490function isLocal() {
3491    return this.isValid() ? !this._isUTC : false;
3492}
3493
3494function isUtcOffset() {
3495    return this.isValid() ? this._isUTC : false;
3496}
3497
3498function isUtc() {
3499    return this.isValid() ? this._isUTC && this._offset === 0 : false;
3500}
3501
3502// ASP.NET json date format regex
3503var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,
3504    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
3505    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
3506    // and further modified to allow for strings containing both week and day
3507    isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
3508
3509function createDuration(input, key) {
3510    var duration = input,
3511        // matching against regexp is expensive, do it on demand
3512        match = null,
3513        sign,
3514        ret,
3515        diffRes;
3516
3517    if (isDuration(input)) {
3518        duration = {
3519            ms: input._milliseconds,
3520            d: input._days,
3521            M: input._months,
3522        };
3523    } else if (isNumber(input) || !isNaN(+input)) {
3524        duration = {};
3525        if (key) {
3526            duration[key] = +input;
3527        } else {
3528            duration.milliseconds = +input;
3529        }
3530    } else if ((match = aspNetRegex.exec(input))) {
3531        sign = match[1] === '-' ? -1 : 1;
3532        duration = {
3533            y: 0,
3534            d: toInt(match[DATE]) * sign,
3535            h: toInt(match[HOUR]) * sign,
3536            m: toInt(match[MINUTE]) * sign,
3537            s: toInt(match[SECOND]) * sign,
3538            ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign, // the millisecond decimal point is included in the match
3539        };
3540    } else if ((match = isoRegex.exec(input))) {
3541        sign = match[1] === '-' ? -1 : 1;
3542        duration = {
3543            y: parseIso(match[2], sign),
3544            M: parseIso(match[3], sign),
3545            w: parseIso(match[4], sign),
3546            d: parseIso(match[5], sign),
3547            h: parseIso(match[6], sign),
3548            m: parseIso(match[7], sign),
3549            s: parseIso(match[8], sign),
3550        };
3551    } else if (duration == null) {
3552        // checks for null or undefined
3553        duration = {};
3554    } else if (
3555        typeof duration === 'object' &&
3556        ('from' in duration || 'to' in duration)
3557    ) {
3558        diffRes = momentsDifference(
3559            createLocal(duration.from),
3560            createLocal(duration.to)
3561        );
3562
3563        duration = {};
3564        duration.ms = diffRes.milliseconds;
3565        duration.M = diffRes.months;
3566    }
3567
3568    ret = new Duration(duration);
3569
3570    if (isDuration(input) && hasOwnProp(input, '_locale')) {
3571        ret._locale = input._locale;
3572    }
3573
3574    if (isDuration(input) && hasOwnProp(input, '_isValid')) {
3575        ret._isValid = input._isValid;
3576    }
3577
3578    return ret;
3579}
3580
3581createDuration.fn = Duration.prototype;
3582createDuration.invalid = createInvalid$1;
3583
3584function parseIso(inp, sign) {
3585    // We'd normally use ~~inp for this, but unfortunately it also
3586    // converts floats to ints.
3587    // inp may be undefined, so careful calling replace on it.
3588    var res = inp && parseFloat(inp.replace(',', '.'));
3589    // apply sign while we're at it
3590    return (isNaN(res) ? 0 : res) * sign;
3591}
3592
3593function positiveMomentsDifference(base, other) {
3594    var res = {};
3595
3596    res.months =
3597        other.month() - base.month() + (other.year() - base.year()) * 12;
3598    if (base.clone().add(res.months, 'M').isAfter(other)) {
3599        --res.months;
3600    }
3601
3602    res.milliseconds = +other - +base.clone().add(res.months, 'M');
3603
3604    return res;
3605}
3606
3607function momentsDifference(base, other) {
3608    var res;
3609    if (!(base.isValid() && other.isValid())) {
3610        return { milliseconds: 0, months: 0 };
3611    }
3612
3613    other = cloneWithOffset(other, base);
3614    if (base.isBefore(other)) {
3615        res = positiveMomentsDifference(base, other);
3616    } else {
3617        res = positiveMomentsDifference(other, base);
3618        res.milliseconds = -res.milliseconds;
3619        res.months = -res.months;
3620    }
3621
3622    return res;
3623}
3624
3625// TODO: remove 'name' arg after deprecation is removed
3626function createAdder(direction, name) {
3627    return function (val, period) {
3628        var dur, tmp;
3629        //invert the arguments, but complain about it
3630        if (period !== null && !isNaN(+period)) {
3631            deprecateSimple(
3632                name,
3633                'moment().' +
3634                    name +
3635                    '(period, number) is deprecated. Please use moment().' +
3636                    name +
3637                    '(number, period). ' +
3638                    'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'
3639            );
3640            tmp = val;
3641            val = period;
3642            period = tmp;
3643        }
3644
3645        dur = createDuration(val, period);
3646        addSubtract(this, dur, direction);
3647        return this;
3648    };
3649}
3650
3651function addSubtract(mom, duration, isAdding, updateOffset) {
3652    var milliseconds = duration._milliseconds,
3653        days = absRound(duration._days),
3654        months = absRound(duration._months);
3655
3656    if (!mom.isValid()) {
3657        // No op
3658        return;
3659    }
3660
3661    updateOffset = updateOffset == null ? true : updateOffset;
3662
3663    if (months) {
3664        setMonth(mom, get(mom, 'Month') + months * isAdding);
3665    }
3666    if (days) {
3667        set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
3668    }
3669    if (milliseconds) {
3670        mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
3671    }
3672    if (updateOffset) {
3673        hooks.updateOffset(mom, days || months);
3674    }
3675}
3676
3677var add = createAdder(1, 'add'),
3678    subtract = createAdder(-1, 'subtract');
3679
3680function isString(input) {
3681    return typeof input === 'string' || input instanceof String;
3682}
3683
3684// type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined
3685function isMomentInput(input) {
3686    return (
3687        isMoment(input) ||
3688        isDate(input) ||
3689        isString(input) ||
3690        isNumber(input) ||
3691        isNumberOrStringArray(input) ||
3692        isMomentInputObject(input) ||
3693        input === null ||
3694        input === undefined
3695    );
3696}
3697
3698function isMomentInputObject(input) {
3699    var objectTest = isObject(input) && !isObjectEmpty(input),
3700        propertyTest = false,
3701        properties = [
3702            'years',
3703            'year',
3704            'y',
3705            'months',
3706            'month',
3707            'M',
3708            'days',
3709            'day',
3710            'd',
3711            'dates',
3712            'date',
3713            'D',
3714            'hours',
3715            'hour',
3716            'h',
3717            'minutes',
3718            'minute',
3719            'm',
3720            'seconds',
3721            'second',
3722            's',
3723            'milliseconds',
3724            'millisecond',
3725            'ms',
3726        ],
3727        i,
3728        property;
3729
3730    for (i = 0; i < properties.length
vendor: 17,272 bytes, lines 3730-4353
3730; i += 1) {
3731        property = properties[i];
3732        propertyTest = propertyTest || hasOwnProp(input, property);
3733    }
3734
3735    return objectTest && propertyTest;
3736}
3737
3738function isNumberOrStringArray(input) {
3739    var arrayTest = isArray(input),
3740        dataTypeTest = false;
3741    if (arrayTest) {
3742        dataTypeTest =
3743            input.filter(function (item) {
3744                return !isNumber(item) && isString(input);
3745            }).length === 0;
3746    }
3747    return arrayTest && dataTypeTest;
3748}
3749
3750function isCalendarSpec(input) {
3751    var objectTest = isObject(input) && !isObjectEmpty(input),
3752        propertyTest = false,
3753        properties = [
3754            'sameDay',
3755            'nextDay',
3756            'lastDay',
3757            'nextWeek',
3758            'lastWeek',
3759            'sameElse',
3760        ],
3761        i,
3762        property;
3763
3764    for (i = 0; i < properties.length; i += 1) {
3765        property = properties[i];
3766        propertyTest = propertyTest || hasOwnProp(input, property);
3767    }
3768
3769    return objectTest && propertyTest;
3770}
3771
3772function getCalendarFormat(myMoment, now) {
3773    var diff = myMoment.diff(now, 'days', true);
3774    return diff < -6
3775        ? 'sameElse'
3776        : diff < -1
3777        ? 'lastWeek'
3778        : diff < 0
3779        ? 'lastDay'
3780        : diff < 1
3781        ? 'sameDay'
3782        : diff < 2
3783        ? 'nextDay'
3784        : diff < 7
3785        ? 'nextWeek'
3786        : 'sameElse';
3787}
3788
3789function calendar$1(time, formats) {
3790    // Support for single parameter, formats only overload to the calendar function
3791    if (arguments.length === 1) {
3792        if (!arguments[0]) {
3793            time = undefined;
3794            formats = undefined;
3795        } else if (isMomentInput(arguments[0])) {
3796            time = arguments[0];
3797            formats = undefined;
3798        } else if (isCalendarSpec(arguments[0])) {
3799            formats = arguments[0];
3800            time = undefined;
3801        }
3802    }
3803    // We want to compare the start of today, vs this.
3804    // Getting start-of-today depends on whether we're local/utc/offset or not.
3805    var now = time || createLocal(),
3806        sod = cloneWithOffset(now, this).startOf('day'),
3807        format = hooks.calendarFormat(this, sod) || 'sameElse',
3808        output =
3809            formats &&
3810            (isFunction(formats[format])
3811                ? formats[format].call(this, now)
3812                : formats[format]);
3813
3814    return this.format(
3815        output || this.localeData().calendar(format, this, createLocal(now))
3816    );
3817}
3818
3819function clone() {
3820    return new Moment(this);
3821}
3822
3823function isAfter(input, units) {
3824    var localInput = isMoment(input) ? input : createLocal(input);
3825    if (!(this.isValid() && localInput.isValid())) {
3826        return false;
3827    }
3828    units = normalizeUnits(units) || 'millisecond';
3829    if (units === 'millisecond') {
3830        return this.valueOf() > localInput.valueOf();
3831    } else {
3832        return localInput.valueOf() < this.clone().startOf(units).valueOf();
3833    }
3834}
3835
3836function isBefore(input, units) {
3837    var localInput = isMoment(input) ? input : createLocal(input);
3838    if (!(this.isValid() && localInput.isValid())) {
3839        return false;
3840    }
3841    units = normalizeUnits(units) || 'millisecond';
3842    if (units === 'millisecond') {
3843        return this.valueOf() < localInput.valueOf();
3844    } else {
3845        return this.clone().endOf(units).valueOf() < localInput.valueOf();
3846    }
3847}
3848
3849function isBetween(from, to, units, inclusivity) {
3850    var localFrom = isMoment(from) ? from : createLocal(from),
3851        localTo = isMoment(to) ? to : createLocal(to);
3852    if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
3853        return false;
3854    }
3855    inclusivity = inclusivity || '()';
3856    return (
3857        (inclusivity[0] === '('
3858            ? this.isAfter(localFrom, units)
3859            : !this.isBefore(localFrom, units)) &&
3860        (inclusivity[1] === ')'
3861            ? this.isBefore(localTo, units)
3862            : !this.isAfter(localTo, units))
3863    );
3864}
3865
3866function isSame(input, units) {
3867    var localInput = isMoment(input) ? input : createLocal(input),
3868        inputMs;
3869    if (!(this.isValid() && localInput.isValid())) {
3870        return false;
3871    }
3872    units = normalizeUnits(units) || 'millisecond';
3873    if (units === 'millisecond') {
3874        return this.valueOf() === localInput.valueOf();
3875    } else {
3876        inputMs = localInput.valueOf();
3877        return (
3878            this.clone().startOf(units).valueOf() <= inputMs &&
3879            inputMs <= this.clone().endOf(units).valueOf()
3880        );
3881    }
3882}
3883
3884function isSameOrAfter(input, units) {
3885    return this.isSame(input, units) || this.isAfter(input, units);
3886}
3887
3888function isSameOrBefore(input, units) {
3889    return this.isSame(input, units) || this.isBefore(input, units);
3890}
3891
3892function diff(input, units, asFloat) {
3893    var that, zoneDelta, output;
3894
3895    if (!this.isValid()) {
3896        return NaN;
3897    }
3898
3899    that = cloneWithOffset(input, this);
3900
3901    if (!that.isValid()) {
3902        return NaN;
3903    }
3904
3905    zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
3906
3907    units = normalizeUnits(units);
3908
3909    switch (units) {
3910        case 'year':
3911            output = monthDiff(this, that) / 12;
3912            break;
3913        case 'month':
3914            output = monthDiff(this, that);
3915            break;
3916        case 'quarter':
3917            output = monthDiff(this, that) / 3;
3918            break;
3919        case 'second':
3920            output = (this - that) / 1e3;
3921            break; // 1000
3922        case 'minute':
3923            output = (this - that) / 6e4;
3924            break; // 1000 * 60
3925        case 'hour':
3926            output = (this - that) / 36e5;
3927            break; // 1000 * 60 * 60
3928        case 'day':
3929            output = (this - that - zoneDelta) / 864e5;
3930            break; // 1000 * 60 * 60 * 24, negate dst
3931        case 'week':
3932            output = (this - that - zoneDelta) / 6048e5;
3933            break; // 1000 * 60 * 60 * 24 * 7, negate dst
3934        default:
3935            output = this - that;
3936    }
3937
3938    return asFloat ? output : absFloor(output);
3939}
3940
3941function monthDiff(a, b) {
3942    if (a.date() < b.date()) {
3943        // end-of-month calculations work correct when the start month has more
3944        // days than the end month.
3945        return -monthDiff(b, a);
3946    }
3947    // difference in months
3948    var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
3949        // b is in (anchor - 1 month, anchor + 1 month)
3950        anchor = a.clone().add(wholeMonthDiff, 'months'),
3951        anchor2,
3952        adjust;
3953
3954    if (b - anchor < 0) {
3955        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
3956        // linear across the month
3957        adjust = (b - anchor) / (anchor - anchor2);
3958    } else {
3959        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
3960        // linear across the month
3961        adjust = (b - anchor) / (anchor2 - anchor);
3962    }
3963
3964    //check for negative zero, return zero if negative zero
3965    return -(wholeMonthDiff + adjust) || 0;
3966}
3967
3968hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
3969hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
3970
3971function toString() {
3972    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
3973}
3974
3975function toISOString(keepOffset) {
3976    if (!this.isValid()) {
3977        return null;
3978    }
3979    var utc = keepOffset !== true,
3980        m = utc ? this.clone().utc() : this;
3981    if (m.year() < 0 || m.year() > 9999) {
3982        return formatMoment(
3983            m,
3984            utc
3985                ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'
3986                : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'
3987        );
3988    }
3989    if (isFunction(Date.prototype.toISOString)) {
3990        // native implementation is ~50x faster, use it when we can
3991        if (utc) {
3992            return this.toDate().toISOString();
3993        } else {
3994            return new Date(this.valueOf() + this.utcOffset() * 60 * 1000)
3995                .toISOString()
3996                .replace('Z', formatMoment(m, 'Z'));
3997        }
3998    }
3999    return formatMoment(
4000        m,
4001        utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'
4002    );
4003}
4004
4005/**
4006 * Return a human readable representation of a moment that can
4007 * also be evaluated to get a new moment which is the same
4008 *
4009 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
4010 */
4011function inspect() {
4012    if (!this.isValid()) {
4013        return 'moment.invalid(/* ' + this._i + ' */)';
4014    }
4015    var func = 'moment',
4016        zone = '',
4017        prefix,
4018        year,
4019        datetime,
4020        suffix;
4021    if (!this.isLocal()) {
4022        func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
4023        zone = 'Z';
4024    }
4025    prefix = '[' + func + '("]';
4026    year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
4027    datetime = '-MM-DD[T]HH:mm:ss.SSS';
4028    suffix = zone + '[")]';
4029
4030    return this.format(prefix + year + datetime + suffix);
4031}
4032
4033function format(inputString) {
4034    if (!inputString) {
4035        inputString = this.isUtc()
4036            ? hooks.defaultFormatUtc
4037            : hooks.defaultFormat;
4038    }
4039    var output = formatMoment(this, inputString);
4040    return this.localeData().postformat(output);
4041}
4042
4043function from(time, withoutSuffix) {
4044    if (
4045        this.isValid() &&
4046        ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
4047    ) {
4048        return createDuration({ to: this, from: time })
4049            .locale(this.locale())
4050            .humanize(!withoutSuffix);
4051    } else {
4052        return this.localeData().invalidDate();
4053    }
4054}
4055
4056function fromNow(withoutSuffix) {
4057    return this.from(createLocal(), withoutSuffix);
4058}
4059
4060function to(time, withoutSuffix) {
4061    if (
4062        this.isValid() &&
4063        ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
4064    ) {
4065        return createDuration({ from: this, to: time })
4066            .locale(this.locale())
4067            .humanize(!withoutSuffix);
4068    } else {
4069        return this.localeData().invalidDate();
4070    }
4071}
4072
4073function toNow(withoutSuffix) {
4074    return this.to(createLocal(), withoutSuffix);
4075}
4076
4077// If passed a locale key, it will set the locale for this
4078// instance.  Otherwise, it will return the locale configuration
4079// variables for this instance.
4080function locale(key) {
4081    var newLocaleData;
4082
4083    if (key === undefined) {
4084        return this._locale._abbr;
4085    } else {
4086        newLocaleData = getLocale(key);
4087        if (newLocaleData != null) {
4088            this._locale = newLocaleData;
4089        }
4090        return this;
4091    }
4092}
4093
4094var lang = deprecate(
4095    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
4096    function (key) {
4097        if (key === undefined) {
4098            return this.localeData();
4099        } else {
4100            return this.locale(key);
4101        }
4102    }
4103);
4104
4105function localeData() {
4106    return this._locale;
4107}
4108
4109var MS_PER_SECOND = 1000,
4110    MS_PER_MINUTE = 60 * MS_PER_SECOND,
4111    MS_PER_HOUR = 60 * MS_PER_MINUTE,
4112    MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
4113
4114// actual modulo - handles negative numbers (for dates before 1970):
4115function mod$1(dividend, divisor) {
4116    return ((dividend % divisor) + divisor) % divisor;
4117}
4118
4119function localStartOfDate(y, m, d) {
4120    // the date constructor remaps years 0-99 to 1900-1999
4121    if (y < 100 && y >= 0) {
4122        // preserve leap years using a full 400 year cycle, then reset
4123        return new Date(y + 400, m, d) - MS_PER_400_YEARS;
4124    } else {
4125        return new Date(y, m, d).valueOf();
4126    }
4127}
4128
4129function utcStartOfDate(y, m, d) {
4130    // Date.UTC remaps years 0-99 to 1900-1999
4131    if (y < 100 && y >= 0) {
4132        // preserve leap years using a full 400 year cycle, then reset
4133        return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
4134    } else {
4135        return Date.UTC(y, m, d);
4136    }
4137}
4138
4139function startOf(units) {
4140    var time, startOfDate;
4141    units = normalizeUnits(units);
4142    if (units === undefined || units === 'millisecond' || !this.isValid()) {
4143        return this;
4144    }
4145
4146    startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
4147
4148    switch (units) {
4149        case 'year':
4150            time = startOfDate(this.year(), 0, 1);
4151            break;
4152        case 'quarter':
4153            time = startOfDate(
4154                this.year(),
4155                this.month() - (this.month() % 3),
4156                1
4157            );
4158            break;
4159        case 'month':
4160            time = startOfDate(this.year(), this.month(), 1);
4161            break;
4162        case 'week':
4163            time = startOfDate(
4164                this.year(),
4165                this.month(),
4166                this.date() - this.weekday()
4167            );
4168            break;
4169        case 'isoWeek':
4170            time = startOfDate(
4171                this.year(),
4172                this.month(),
4173                this.date() - (this.isoWeekday() - 1)
4174            );
4175            break;
4176        case 'day':
4177        case 'date':
4178            time = startOfDate(this.year(), this.month(), this.date());
4179            break;
4180        case 'hour':
4181            time = this._d.valueOf();
4182            time -= mod$1(
4183                time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
4184                MS_PER_HOUR
4185            );
4186            break;
4187        case 'minute':
4188            time = this._d.valueOf();
4189            time -= mod$1(time, MS_PER_MINUTE);
4190            break;
4191        case 'second':
4192            time = this._d.valueOf();
4193            time -= mod$1(time, MS_PER_SECOND);
4194            break;
4195    }
4196
4197    this._d.setTime(time);
4198    hooks.updateOffset(this, true);
4199    return this;
4200}
4201
4202function endOf(units) {
4203    var time, startOfDate;
4204    units = normalizeUnits(units);
4205    if (units === undefined || units === 'millisecond' || !this.isValid()) {
4206        return this;
4207    }
4208
4209    startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
4210
4211    switch (units) {
4212        case 'year':
4213            time = startOfDate(this.year() + 1, 0, 1) - 1;
4214            break;
4215        case 'quarter':
4216            time =
4217                startOfDate(
4218                    this.year(),
4219                    this.month() - (this.month() % 3) + 3,
4220                    1
4221                ) - 1;
4222            break;
4223        case 'month':
4224            time = startOfDate(this.year(), this.month() + 1, 1) - 1;
4225            break;
4226        case 'week':
4227            time =
4228                startOfDate(
4229                    this.year(),
4230                    this.month(),
4231                    this.date() - this.weekday() + 7
4232                ) - 1;
4233            break;
4234        case 'isoWeek':
4235            time =
4236                startOfDate(
4237                    this.year(),
4238                    this.month(),
4239                    this.date() - (this.isoWeekday() - 1) + 7
4240                ) - 1;
4241            break;
4242        case 'day':
4243        case 'date':
4244            time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
4245            break;
4246        case 'hour':
4247            time = this._d.valueOf();
4248            time +=
4249                MS_PER_HOUR -
4250                mod$1(
4251                    time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
4252                    MS_PER_HOUR
4253                ) -
4254                1;
4255            break;
4256        case 'minute':
4257            time = this._d.valueOf();
4258            time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
4259            break;
4260        case 'second':
4261            time = this._d.valueOf();
4262            time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
4263            break;
4264    }
4265
4266    this._d.setTime(time);
4267    hooks.updateOffset(this, true);
4268    return this;
4269}
4270
4271function valueOf() {
4272    return this._d.valueOf() - (this._offset || 0) * 60000;
4273}
4274
4275function unix() {
4276    return Math.floor(this.valueOf() / 1000);
4277}
4278
4279function toDate() {
4280    return new Date(this.valueOf());
4281}
4282
4283function toArray() {
4284    var m = this;
4285    return [
4286        m.year(),
4287        m.month(),
4288        m.date(),
4289        m.hour(),
4290        m.minute(),
4291        m.second(),
4292        m.millisecond(),
4293    ];
4294}
4295
4296function toObject() {
4297    var m = this;
4298    return {
4299        years: m.year(),
4300        months: m.month(),
4301        date: m.date(),
4302        hours: m.hours(),
4303        minutes: m.minutes(),
4304        seconds: m.seconds(),
4305        milliseconds: m.milliseconds(),
4306    };
4307}
4308
4309function toJSON() {
4310    // new Date(NaN).toJSON() === null
4311    return this.isValid() ? this.toISOString() : null;
4312}
4313
4314function isValid$2() {
4315    return isValid(this);
4316}
4317
4318function parsingFlags() {
4319    return extend({}, getParsingFlags(this));
4320}
4321
4322function invalidAt() {
4323    return getParsingFlags(this).overflow;
4324}
4325
4326function creationData() {
4327    return {
4328        input: this._i,
4329        format: this._f,
4330        locale: this._locale,
4331        isUTC: this._isUTC,
4332        strict: this._strict,
4333    };
4334}
4335
4336addFormatToken('N', 0, 0, 'eraAbbr');
4337addFormatToken('NN', 0, 0, 'eraAbbr');
4338addFormatToken('NNN', 0, 0, 'eraAbbr');
4339addFormatToken('NNNN', 0, 0, 'eraName');
4340addFormatToken('NNNNN', 0, 0, 'eraNarrow');
4341
4342addFormatToken('y', ['y', 1], 'yo', 'eraYear');
4343addFormatToken('y', ['yy', 2], 0, 'eraYear');
4344addFormatToken('y', ['yyy', 3], 0, 'eraYear');
4345addFormatToken('y', ['yyyy', 4], 0, 'eraYear');
4346
4347addRegexToken('N', matchEraAbbr);
4348addRegexToken('NN', matchEraAbbr);
4349addRegexToken('NNN', matchEraAbbr);
4350addRegexToken('NNNN', matchEraName);
4351addRegexToken('NNNNN', matchEraNarrow);
4352
4353addParseToken(
vendor: 8,018 bytes, lines 4353-4664
4353['N', 'NN', 'NNN', 'NNNN', 'NNNNN'], function (
4354    input,
4355    array,
4356    config,
4357    token
4358) {
4359    var era = config._locale.erasParse(input, token, config._strict);
4360    if (era) {
4361        getParsingFlags(config).era = era;
4362    } else {
4363        getParsingFlags(config).invalidEra = input;
4364    }
4365});
4366
4367addRegexToken('y', matchUnsigned);
4368addRegexToken('yy', matchUnsigned);
4369addRegexToken('yyy', matchUnsigned);
4370addRegexToken('yyyy', matchUnsigned);
4371addRegexToken('yo', matchEraYearOrdinal);
4372
4373addParseToken(['y', 'yy', 'yyy', 'yyyy'], YEAR);
4374addParseToken(['yo'], function (input, array, config, token) {
4375    var match;
4376    if (config._locale._eraYearOrdinalRegex) {
4377        match = input.match(config._locale._eraYearOrdinalRegex);
4378    }
4379
4380    if (config._locale.eraYearOrdinalParse) {
4381        array[YEAR] = config._locale.eraYearOrdinalParse(input, match);
4382    } else {
4383        array[YEAR] = parseInt(input, 10);
4384    }
4385});
4386
4387function localeEras(m, format) {
4388    var i,
4389        l,
4390        date,
4391        eras = this._eras || getLocale('en')._eras;
4392    for (i = 0, l = eras.length; i < l; ++i) {
4393        switch (typeof eras[i].since) {
4394            case 'string':
4395                // truncate time
4396                date = hooks(eras[i].since).startOf('day');
4397                eras[i].since = date.valueOf();
4398                break;
4399        }
4400
4401        switch (typeof eras[i].until) {
4402            case 'undefined':
4403                eras[i].until = +Infinity;
4404                break;
4405            case 'string':
4406                // truncate time
4407                date = hooks(eras[i].until).startOf('day').valueOf();
4408                eras[i].until = date.valueOf();
4409                break;
4410        }
4411    }
4412    return eras;
4413}
4414
4415function localeErasParse(eraName, format, strict) {
4416    var i,
4417        l,
4418        eras = this.eras(),
4419        name,
4420        abbr,
4421        narrow;
4422    eraName = eraName.toUpperCase();
4423
4424    for (i = 0, l = eras.length; i < l; ++i) {
4425        name = eras[i].name.toUpperCase();
4426        abbr = eras[i].abbr.toUpperCase();
4427        narrow = eras[i].narrow.toUpperCase();
4428
4429        if (strict) {
4430            switch (format) {
4431                case 'N':
4432                case 'NN':
4433                case 'NNN':
4434                    if (abbr === eraName) {
4435                        return eras[i];
4436                    }
4437                    break;
4438
4439                case 'NNNN':
4440                    if (name === eraName) {
4441                        return eras[i];
4442                    }
4443                    break;
4444
4445                case 'NNNNN':
4446                    if (narrow === eraName) {
4447                        return eras[i];
4448                    }
4449                    break;
4450            }
4451        } else if ([name, abbr, narrow].indexOf(eraName) >= 0) {
4452            return eras[i];
4453        }
4454    }
4455}
4456
4457function localeErasConvertYear(era, year) {
4458    var dir = era.since <= era.until ? +1 : -1;
4459    if (year === undefined) {
4460        return hooks(era.since).year();
4461    } else {
4462        return hooks(era.since).year() + (year - era.offset) * dir;
4463    }
4464}
4465
4466function getEraName() {
4467    var i,
4468        l,
4469        val,
4470        eras = this.localeData().eras();
4471    for (i = 0, l = eras.length; i < l; ++i) {
4472        // truncate time
4473        val = this.clone().startOf('day').valueOf();
4474
4475        if (eras[i].since <= val && val <= eras[i].until) {
4476            return eras[i].name;
4477        }
4478        if (eras[i].until <= val && val <= eras[i].since) {
4479            return eras[i].name;
4480        }
4481    }
4482
4483    return '';
4484}
4485
4486function getEraNarrow() {
4487    var i,
4488        l,
4489        val,
4490        eras = this.localeData().eras();
4491    for (i = 0, l = eras.length; i < l; ++i) {
4492        // truncate time
4493        val = this.clone().startOf('day').valueOf();
4494
4495        if (eras[i].since <= val && val <= eras[i].until) {
4496            return eras[i].narrow;
4497        }
4498        if (eras[i].until <= val && val <= eras[i].since) {
4499            return eras[i].narrow;
4500        }
4501    }
4502
4503    return '';
4504}
4505
4506function getEraAbbr() {
4507    var i,
4508        l,
4509        val,
4510        eras = this.localeData().eras();
4511    for (i = 0, l = eras.length; i < l; ++i) {
4512        // truncate time
4513        val = this.clone().startOf('day').valueOf();
4514
4515        if (eras[i].since <= val && val <= eras[i].until) {
4516            return eras[i].abbr;
4517        }
4518        if (eras[i].until <= val && val <= eras[i].since) {
4519            return eras[i].abbr;
4520        }
4521    }
4522
4523    return '';
4524}
4525
4526function getEraYear() {
4527    var i,
4528        l,
4529        dir,
4530        val,
4531        eras = this.localeData().eras();
4532    for (i = 0, l = eras.length; i < l; ++i) {
4533        dir = eras[i].since <= eras[i].until ? +1 : -1;
4534
4535        // truncate time
4536        val = this.clone().startOf('day').valueOf();
4537
4538        if (
4539            (eras[i].since <= val && val <= eras[i].until) ||
4540            (eras[i].until <= val && val <= eras[i].since)
4541        ) {
4542            return (
4543                (this.year() - hooks(eras[i].since).year()) * dir +
4544                eras[i].offset
4545            );
4546        }
4547    }
4548
4549    return this.year();
4550}
4551
4552function erasNameRegex(isStrict) {
4553    if (!hasOwnProp(this, '_erasNameRegex')) {
4554        computeErasParse.call(this);
4555    }
4556    return isStrict ? this._erasNameRegex : this._erasRegex;
4557}
4558
4559function erasAbbrRegex(isStrict) {
4560    if (!hasOwnProp(this, '_erasAbbrRegex')) {
4561        computeErasParse.call(this);
4562    }
4563    return isStrict ? this._erasAbbrRegex : this._erasRegex;
4564}
4565
4566function erasNarrowRegex(isStrict) {
4567    if (!hasOwnProp(this, '_erasNarrowRegex')) {
4568        computeErasParse.call(this);
4569    }
4570    return isStrict ? this._erasNarrowRegex : this._erasRegex;
4571}
4572
4573function matchEraAbbr(isStrict, locale) {
4574    return locale.erasAbbrRegex(isStrict);
4575}
4576
4577function matchEraName(isStrict, locale) {
4578    return locale.erasNameRegex(isStrict);
4579}
4580
4581function matchEraNarrow(isStrict, locale) {
4582    return locale.erasNarrowRegex(isStrict);
4583}
4584
4585function matchEraYearOrdinal(isStrict, locale) {
4586    return locale._eraYearOrdinalRegex || matchUnsigned;
4587}
4588
4589function computeErasParse() {
4590    var abbrPieces = [],
4591        namePieces = [],
4592        narrowPieces = [],
4593        mixedPieces = [],
4594        i,
4595        l,
4596        eras = this.eras();
4597
4598    for (i = 0, l = eras.length; i < l; ++i) {
4599        namePieces.push(regexEscape(eras[i].name));
4600        abbrPieces.push(regexEscape(eras[i].abbr));
4601        narrowPieces.push(regexEscape(eras[i].narrow));
4602
4603        mixedPieces.push(regexEscape(eras[i].name));
4604        mixedPieces.push(regexEscape(eras[i].abbr));
4605        mixedPieces.push(regexEscape(eras[i].narrow));
4606    }
4607
4608    this._erasRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
4609    this._erasNameRegex = new RegExp('^(' + namePieces.join('|') + ')', 'i');
4610    this._erasAbbrRegex = new RegExp('^(' + abbrPieces.join('|') + ')', 'i');
4611    this._erasNarrowRegex = new RegExp(
4612        '^(' + narrowPieces.join('|') + ')',
4613        'i'
4614    );
4615}
4616
4617// FORMATTING
4618
4619addFormatToken(0, ['gg', 2], 0, function () {
4620    return this.weekYear() % 100;
4621});
4622
4623addFormatToken(0, ['GG', 2], 0, function () {
4624    return this.isoWeekYear() % 100;
4625});
4626
4627function addWeekYearFormatToken(token, getter) {
4628    addFormatToken(0, [token, token.length], 0, getter);
4629}
4630
4631addWeekYearFormatToken('gggg', 'weekYear');
4632addWeekYearFormatToken('ggggg', 'weekYear');
4633addWeekYearFormatToken('GGGG', 'isoWeekYear');
4634addWeekYearFormatToken('GGGGG', 'isoWeekYear');
4635
4636// ALIASES
4637
4638addUnitAlias('weekYear', 'gg');
4639addUnitAlias('isoWeekYear', 'GG');
4640
4641// PRIORITY
4642
4643addUnitPriority('weekYear', 1);
4644addUnitPriority('isoWeekYear', 1);
4645
4646// PARSING
4647
4648addRegexToken('G', matchSigned);
4649addRegexToken('g', matchSigned);
4650addRegexToken('GG', match1to2, match2);
4651addRegexToken('gg', match1to2, match2);
4652addRegexToken('GGGG', match1to4, match4);
4653addRegexToken('gggg', match1to4, match4);
4654addRegexToken('GGGGG', match1to6, match6);
4655addRegexToken('ggggg', match1to6, match6);
4656
4657addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (
4658    input,
4659    week,
4660    config,
4661    token
4662) {
4663    week[token.substr(0, 2)] = toInt(input);
4664}
vendor: 26,165 bytes, lines 4664-5687
4664);
4665
4666addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
4667    week[token] = hooks.parseTwoDigitYear(input);
4668});
4669
4670// MOMENTS
4671
4672function getSetWeekYear(input) {
4673    return getSetWeekYearHelper.call(
4674        this,
4675        input,
4676        this.week(),
4677        this.weekday(),
4678        this.localeData()._week.dow,
4679        this.localeData()._week.doy
4680    );
4681}
4682
4683function getSetISOWeekYear(input) {
4684    return getSetWeekYearHelper.call(
4685        this,
4686        input,
4687        this.isoWeek(),
4688        this.isoWeekday(),
4689        1,
4690        4
4691    );
4692}
4693
4694function getISOWeeksInYear() {
4695    return weeksInYear(this.year(), 1, 4);
4696}
4697
4698function getISOWeeksInISOWeekYear() {
4699    return weeksInYear(this.isoWeekYear(), 1, 4);
4700}
4701
4702function getWeeksInYear() {
4703    var weekInfo = this.localeData()._week;
4704    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
4705}
4706
4707function getWeeksInWeekYear() {
4708    var weekInfo = this.localeData()._week;
4709    return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy);
4710}
4711
4712function getSetWeekYearHelper(input, week, weekday, dow, doy) {
4713    var weeksTarget;
4714    if (input == null) {
4715        return weekOfYear(this, dow, doy).year;
4716    } else {
4717        weeksTarget = weeksInYear(input, dow, doy);
4718        if (week > weeksTarget) {
4719            week = weeksTarget;
4720        }
4721        return setWeekAll.call(this, input, week, weekday, dow, doy);
4722    }
4723}
4724
4725function setWeekAll(weekYear, week, weekday, dow, doy) {
4726    var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
4727        date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
4728
4729    this.year(date.getUTCFullYear());
4730    this.month(date.getUTCMonth());
4731    this.date(date.getUTCDate());
4732    return this;
4733}
4734
4735// FORMATTING
4736
4737addFormatToken('Q', 0, 'Qo', 'quarter');
4738
4739// ALIASES
4740
4741addUnitAlias('quarter', 'Q');
4742
4743// PRIORITY
4744
4745addUnitPriority('quarter', 7);
4746
4747// PARSING
4748
4749addRegexToken('Q', match1);
4750addParseToken('Q', function (input, array) {
4751    array[MONTH] = (toInt(input) - 1) * 3;
4752});
4753
4754// MOMENTS
4755
4756function getSetQuarter(input) {
4757    return input == null
4758        ? Math.ceil((this.month() + 1) / 3)
4759        : this.month((input - 1) * 3 + (this.month() % 3));
4760}
4761
4762// FORMATTING
4763
4764addFormatToken('D', ['DD', 2], 'Do', 'date');
4765
4766// ALIASES
4767
4768addUnitAlias('date', 'D');
4769
4770// PRIORITY
4771addUnitPriority('date', 9);
4772
4773// PARSING
4774
4775addRegexToken('D', match1to2);
4776addRegexToken('DD', match1to2, match2);
4777addRegexToken('Do', function (isStrict, locale) {
4778    // TODO: Remove "ordinalParse" fallback in next major release.
4779    return isStrict
4780        ? locale._dayOfMonthOrdinalParse || locale._ordinalParse
4781        : locale._dayOfMonthOrdinalParseLenient;
4782});
4783
4784addParseToken(['D', 'DD'], DATE);
4785addParseToken('Do', function (input, array) {
4786    array[DATE] = toInt(input.match(match1to2)[0]);
4787});
4788
4789// MOMENTS
4790
4791var getSetDayOfMonth = makeGetSet('Date', true);
4792
4793// FORMATTING
4794
4795addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
4796
4797// ALIASES
4798
4799addUnitAlias('dayOfYear', 'DDD');
4800
4801// PRIORITY
4802addUnitPriority('dayOfYear', 4);
4803
4804// PARSING
4805
4806addRegexToken('DDD', match1to3);
4807addRegexToken('DDDD', match3);
4808addParseToken(['DDD', 'DDDD'], function (input, array, config) {
4809    config._dayOfYear = toInt(input);
4810});
4811
4812// HELPERS
4813
4814// MOMENTS
4815
4816function getSetDayOfYear(input) {
4817    var dayOfYear =
4818        Math.round(
4819            (this.clone().startOf('day') - this.clone().startOf('year')) / 864e5
4820        ) + 1;
4821    return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
4822}
4823
4824// FORMATTING
4825
4826addFormatToken('m', ['mm', 2], 0, 'minute');
4827
4828// ALIASES
4829
4830addUnitAlias('minute', 'm');
4831
4832// PRIORITY
4833
4834addUnitPriority('minute', 14);
4835
4836// PARSING
4837
4838addRegexToken('m', match1to2);
4839addRegexToken('mm', match1to2, match2);
4840addParseToken(['m', 'mm'], MINUTE);
4841
4842// MOMENTS
4843
4844var getSetMinute = makeGetSet('Minutes', false);
4845
4846// FORMATTING
4847
4848addFormatToken('s', ['ss', 2], 0, 'second');
4849
4850// ALIASES
4851
4852addUnitAlias('second', 's');
4853
4854// PRIORITY
4855
4856addUnitPriority('second', 15);
4857
4858// PARSING
4859
4860addRegexToken('s', match1to2);
4861addRegexToken('ss', match1to2, match2);
4862addParseToken(['s', 'ss'], SECOND);
4863
4864// MOMENTS
4865
4866var getSetSecond = makeGetSet('Seconds', false);
4867
4868// FORMATTING
4869
4870addFormatToken('S', 0, 0, function () {
4871    return ~~(this.millisecond() / 100);
4872});
4873
4874addFormatToken(0, ['SS', 2], 0, function () {
4875    return ~~(this.millisecond() / 10);
4876});
4877
4878addFormatToken(0, ['SSS', 3], 0, 'millisecond');
4879addFormatToken(0, ['SSSS', 4], 0, function () {
4880    return this.millisecond() * 10;
4881});
4882addFormatToken(0, ['SSSSS', 5], 0, function () {
4883    return this.millisecond() * 100;
4884});
4885addFormatToken(0, ['SSSSSS', 6], 0, function () {
4886    return this.millisecond() * 1000;
4887});
4888addFormatToken(0, ['SSSSSSS', 7], 0, function () {
4889    return this.millisecond() * 10000;
4890});
4891addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
4892    return this.millisecond() * 100000;
4893});
4894addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
4895    return this.millisecond() * 1000000;
4896});
4897
4898// ALIASES
4899
4900addUnitAlias('millisecond', 'ms');
4901
4902// PRIORITY
4903
4904addUnitPriority('millisecond', 16);
4905
4906// PARSING
4907
4908addRegexToken('S', match1to3, match1);
4909addRegexToken('SS', match1to3, match2);
4910addRegexToken('SSS', match1to3, match3);
4911
4912var token, getSetMillisecond;
4913for (token = 'SSSS'; token.length <= 9; token += 'S') {
4914    addRegexToken(token, matchUnsigned);
4915}
4916
4917function parseMs(input, array) {
4918    array[MILLISECOND] = toInt(('0.' + input) * 1000);
4919}
4920
4921for (token = 'S'; token.length <= 9; token += 'S') {
4922    addParseToken(token, parseMs);
4923}
4924
4925getSetMillisecond = makeGetSet('Milliseconds', false);
4926
4927// FORMATTING
4928
4929addFormatToken('z', 0, 0, 'zoneAbbr');
4930addFormatToken('zz', 0, 0, 'zoneName');
4931
4932// MOMENTS
4933
4934function getZoneAbbr() {
4935    return this._isUTC ? 'UTC' : '';
4936}
4937
4938function getZoneName() {
4939    return this._isUTC ? 'Coordinated Universal Time' : '';
4940}
4941
4942var proto = Moment.prototype;
4943
4944proto.add = add;
4945proto.calendar = calendar$1;
4946proto.clone = clone;
4947proto.diff = diff;
4948proto.endOf = endOf;
4949proto.format = format;
4950proto.from = from;
4951proto.fromNow = fromNow;
4952proto.to = to;
4953proto.toNow = toNow;
4954proto.get = stringGet;
4955proto.invalidAt = invalidAt;
4956proto.isAfter = isAfter;
4957proto.isBefore = isBefore;
4958proto.isBetween = isBetween;
4959proto.isSame = isSame;
4960proto.isSameOrAfter = isSameOrAfter;
4961proto.isSameOrBefore = isSameOrBefore;
4962proto.isValid = isValid$2;
4963proto.lang = lang;
4964proto.locale = locale;
4965proto.localeData = localeData;
4966proto.max = prototypeMax;
4967proto.min = prototypeMin;
4968proto.parsingFlags = parsingFlags;
4969proto.set = stringSet;
4970proto.startOf = startOf;
4971proto.subtract = subtract;
4972proto.toArray = toArray;
4973proto.toObject = toObject;
4974proto.toDate = toDate;
4975proto.toISOString = toISOString;
4976proto.inspect = inspect;
4977if (typeof Symbol !== 'undefined' && Symbol.for != null) {
4978    proto[Symbol.for('nodejs.util.inspect.custom')] = function () {
4979        return 'Moment<' + this.format() + '>';
4980    };
4981}
4982proto.toJSON = toJSON;
4983proto.toString = toString;
4984proto.unix = unix;
4985proto.valueOf = valueOf;
4986proto.creationData = creationData;
4987proto.eraName = getEraName;
4988proto.eraNarrow = getEraNarrow;
4989proto.eraAbbr = getEraAbbr;
4990proto.eraYear = getEraYear;
4991proto.year = getSetYear;
4992proto.isLeapYear = getIsLeapYear;
4993proto.weekYear = getSetWeekYear;
4994proto.isoWeekYear = getSetISOWeekYear;
4995proto.quarter = proto.quarters = getSetQuarter;
4996proto.month = getSetMonth;
4997proto.daysInMonth = getDaysInMonth;
4998proto.week = proto.weeks = getSetWeek;
4999proto.isoWeek = proto.isoWeeks = getSetISOWeek;
5000proto.weeksInYear = getWeeksInYear;
5001proto.weeksInWeekYear = getWeeksInWeekYear;
5002proto.isoWeeksInYear = getISOWeeksInYear;
5003proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear;
5004proto.date = getSetDayOfMonth;
5005proto.day = proto.days = getSetDayOfWeek;
5006proto.weekday = getSetLocaleDayOfWeek;
5007proto.isoWeekday = getSetISODayOfWeek;
5008proto.dayOfYear = getSetDayOfYear;
5009proto.hour = proto.hours = getSetHour;
5010proto.minute = proto.minutes = getSetMinute;
5011proto.second = proto.seconds = getSetSecond;
5012proto.millisecond = proto.milliseconds = getSetMillisecond;
5013proto.utcOffset = getSetOffset;
5014proto.utc = setOffsetToUTC;
5015proto.local = setOffsetToLocal;
5016proto.parseZone = setOffsetToParsedOffset;
5017proto.hasAlignedHourOffset = hasAlignedHourOffset;
5018proto.isDST = isDaylightSavingTime;
5019proto.isLocal = isLocal;
5020proto.isUtcOffset = isUtcOffset;
5021proto.isUtc = isUtc;
5022proto.isUTC = isUtc;
5023proto.zoneAbbr = getZoneAbbr;
5024proto.zoneName = getZoneName;
5025proto.dates = deprecate(
5026    'dates accessor is deprecated. Use date instead.',
5027    getSetDayOfMonth
5028);
5029proto.months = deprecate(
5030    'months accessor is deprecated. Use month instead',
5031    getSetMonth
5032);
5033proto.years = deprecate(
5034    'years accessor is deprecated. Use year instead',
5035    getSetYear
5036);
5037proto.zone = deprecate(
5038    'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/',
5039    getSetZone
5040);
5041proto.isDSTShifted = deprecate(
5042    'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information',
5043    isDaylightSavingTimeShifted
5044);
5045
5046function createUnix(input) {
5047    return createLocal(input * 1000);
5048}
5049
5050function createInZone() {
5051    return createLocal.apply(null, arguments).parseZone();
5052}
5053
5054function preParsePostFormat(string) {
5055    return string;
5056}
5057
5058var proto$1 = Locale.prototype;
5059
5060proto$1.calendar = calendar;
5061proto$1.longDateFormat = longDateFormat;
5062proto$1.invalidDate = invalidDate;
5063proto$1.ordinal = ordinal;
5064proto$1.preparse = preParsePostFormat;
5065proto$1.postformat = preParsePostFormat;
5066proto$1.relativeTime = relativeTime;
5067proto$1.pastFuture = pastFuture;
5068proto$1.set = set;
5069proto$1.eras = localeEras;
5070proto$1.erasParse = localeErasParse;
5071proto$1.erasConvertYear = localeErasConvertYear;
5072proto$1.erasAbbrRegex = erasAbbrRegex;
5073proto$1.erasNameRegex = erasNameRegex;
5074proto$1.erasNarrowRegex = erasNarrowRegex;
5075
5076proto$1.months = localeMonths;
5077proto$1.monthsShort = localeMonthsShort;
5078proto$1.monthsParse = localeMonthsParse;
5079proto$1.monthsRegex = monthsRegex;
5080proto$1.monthsShortRegex = monthsShortRegex;
5081proto$1.week = localeWeek;
5082proto$1.firstDayOfYear = localeFirstDayOfYear;
5083proto$1.firstDayOfWeek = localeFirstDayOfWeek;
5084
5085proto$1.weekdays = localeWeekdays;
5086proto$1.weekdaysMin = localeWeekdaysMin;
5087proto$1.weekdaysShort = localeWeekdaysShort;
5088proto$1.weekdaysParse = localeWeekdaysParse;
5089
5090proto$1.weekdaysRegex = weekdaysRegex;
5091proto$1.weekdaysShortRegex = weekdaysShortRegex;
5092proto$1.weekdaysMinRegex = weekdaysMinRegex;
5093
5094proto$1.isPM = localeIsPM;
5095proto$1.meridiem = localeMeridiem;
5096
5097function get$1(format, index, field, setter) {
5098    var locale = getLocale(),
5099        utc = createUTC().set(setter, index);
5100    return locale[field](utc, format);
5101}
5102
5103function listMonthsImpl(format, index, field) {
5104    if (isNumber(format)) {
5105        index = format;
5106        format = undefined;
5107    }
5108
5109    format = format || '';
5110
5111    if (index != null) {
5112        return get$1(format, index, field, 'month');
5113    }
5114
5115    var i,
5116        out = [];
5117    for (i = 0; i < 12; i++) {
5118        out[i] = get$1(format, i, field, 'month');
5119    }
5120    return out;
5121}
5122
5123// ()
5124// (5)
5125// (fmt, 5)
5126// (fmt)
5127// (true)
5128// (true, 5)
5129// (true, fmt, 5)
5130// (true, fmt)
5131function listWeekdaysImpl(localeSorted, format, index, field) {
5132    if (typeof localeSorted === 'boolean') {
5133        if (isNumber(format)) {
5134            index = format;
5135            format = undefined;
5136        }
5137
5138        format = format || '';
5139    } else {
5140        format = localeSorted;
5141        index = format;
5142        localeSorted = false;
5143
5144        if (isNumber(format)) {
5145            index = format;
5146            format = undefined;
5147        }
5148
5149        format = format || '';
5150    }
5151
5152    var locale = getLocale(),
5153        shift = localeSorted ? locale._week.dow : 0,
5154        i,
5155        out = [];
5156
5157    if (index != null) {
5158        return get$1(format, (index + shift) % 7, field, 'day');
5159    }
5160
5161    for (i = 0; i < 7; i++) {
5162        out[i] = get$1(format, (i + shift) % 7, field, 'day');
5163    }
5164    return out;
5165}
5166
5167function listMonths(format, index) {
5168    return listMonthsImpl(format, index, 'months');
5169}
5170
5171function listMonthsShort(format, index) {
5172    return listMonthsImpl(format, index, 'monthsShort');
5173}
5174
5175function listWeekdays(localeSorted, format, index) {
5176    return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
5177}
5178
5179function listWeekdaysShort(localeSorted, format, index) {
5180    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
5181}
5182
5183function listWeekdaysMin(localeSorted, format, index) {
5184    return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
5185}
5186
5187getSetGlobalLocale('en', {
5188    eras: [
5189        {
5190            since: '0001-01-01',
5191            until: +Infinity,
5192            offset: 1,
5193            name: 'Anno Domini',
5194            narrow: 'AD',
5195            abbr: 'AD',
5196        },
5197        {
5198            since: '0000-12-31',
5199            until: -Infinity,
5200            offset: 1,
5201            name: 'Before Christ',
5202            narrow: 'BC',
5203            abbr: 'BC',
5204        },
5205    ],
5206    dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
5207    ordinal: function (number) {
5208        var b = number % 10,
5209            output =
5210                toInt((number % 100) / 10) === 1
5211                    ? 'th'
5212                    : b === 1
5213                    ? 'st'
5214                    : b === 2
5215                    ? 'nd'
5216                    : b === 3
5217                    ? 'rd'
5218                    : 'th';
5219        return number + output;
5220    },
5221});
5222
5223// Side effect imports
5224
5225hooks.lang = deprecate(
5226    'moment.lang is deprecated. Use moment.locale instead.',
5227    getSetGlobalLocale
5228);
5229hooks.langData = deprecate(
5230    'moment.langData is deprecated. Use moment.localeData instead.',
5231    getLocale
5232);
5233
5234var mathAbs = Math.abs;
5235
5236function abs() {
5237    var data = this._data;
5238
5239    this._milliseconds = mathAbs(this._milliseconds);
5240    this._days = mathAbs(this._days);
5241    this._months = mathAbs(this._months);
5242
5243    data.milliseconds = mathAbs(data.milliseconds);
5244    data.seconds = mathAbs(data.seconds);
5245    data.minutes = mathAbs(data.minutes);
5246    data.hours = mathAbs(data.hours);
5247    data.months = mathAbs(data.months);
5248    data.years = mathAbs(data.years);
5249
5250    return this;
5251}
5252
5253function addSubtract$1(duration, input, value, direction) {
5254    var other = createDuration(input, value);
5255
5256    duration._milliseconds += direction * other._milliseconds;
5257    duration._days += direction * other._days;
5258    duration._months += direction * other._months;
5259
5260    return duration._bubble();
5261}
5262
5263// supports only 2.0-style add(1, 's') or add(duration)
5264function add$1(input, value) {
5265    return addSubtract$1(this, input, value, 1);
5266}
5267
5268// supports only 2.0-style subtract(1, 's') or subtract(duration)
5269function subtract$1(input, value) {
5270    return addSubtract$1(this, input, value, -1);
5271}
5272
5273function absCeil(number) {
5274    if (number < 0) {
5275        return Math.floor(number);
5276    } else {
5277        return Math.ceil(number);
5278    }
5279}
5280
5281function bubble() {
5282    var milliseconds = this._milliseconds,
5283        days = this._days,
5284        months = this._months,
5285        data = this._data,
5286        seconds,
5287        minutes,
5288        hours,
5289        years,
5290        monthsFromDays;
5291
5292    // if we have a mix of positive and negative values, bubble down first
5293    // check: https://github.com/moment/moment/issues/2166
5294    if (
5295        !(
5296            (milliseconds >= 0 && days >= 0 && months >= 0) ||
5297            (milliseconds <= 0 && days <= 0 && months <= 0)
5298        )
5299    ) {
5300        milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
5301        days = 0;
5302        months = 0;
5303    }
5304
5305    // The following code bubbles up values, see the tests for
5306    // examples of what that means.
5307    data.milliseconds = milliseconds % 1000;
5308
5309    seconds = absFloor(milliseconds / 1000);
5310    data.seconds = seconds % 60;
5311
5312    minutes = absFloor(seconds / 60);
5313    data.minutes = minutes % 60;
5314
5315    hours = absFloor(minutes / 60);
5316    data.hours = hours % 24;
5317
5318    days += absFloor(hours / 24);
5319
5320    // convert days to months
5321    monthsFromDays = absFloor(daysToMonths(days));
5322    months += monthsFromDays;
5323    days -= absCeil(monthsToDays(monthsFromDays));
5324
5325    // 12 months -> 1 year
5326    years = absFloor(months / 12);
5327    months %= 12;
5328
5329    data.days = days;
5330    data.months = months;
5331    data.years = years;
5332
5333    return this;
5334}
5335
5336function daysToMonths(days) {
5337    // 400 years have 146097 days (taking into account leap year rules)
5338    // 400 years have 12 months === 4800
5339    return (days * 4800) / 146097;
5340}
5341
5342function monthsToDays(months) {
5343    // the reverse of daysToMonths
5344    return (months * 146097) / 4800;
5345}
5346
5347function as(units) {
5348    if (!this.isValid()) {
5349        return NaN;
5350    }
5351    var days,
5352        months,
5353        milliseconds = this._milliseconds;
5354
5355    units = normalizeUnits(units);
5356
5357    if (units === 'month' || units === 'quarter' || units === 'year') {
5358        days = this._days + milliseconds / 864e5;
5359        months = this._months + daysToMonths(days);
5360        switch (units) {
5361            case 'month':
5362                return months;
5363            case 'quarter':
5364                return months / 3;
5365            case 'year':
5366                return months / 12;
5367        }
5368    } else {
5369        // handle milliseconds separately because of floating point math errors (issue #1867)
5370        days = this._days + Math.round(monthsToDays(this._months));
5371        switch (units) {
5372            case 'week':
5373                return days / 7 + milliseconds / 6048e5;
5374            case 'day':
5375                return days + milliseconds / 864e5;
5376            case 'hour':
5377                return days * 24 + milliseconds / 36e5;
5378            case 'minute':
5379                return days * 1440 + milliseconds / 6e4;
5380            case 'second':
5381                return days * 86400 + milliseconds / 1000;
5382            // Math.floor prevents floating point math errors here
5383            case 'millisecond':
5384                return Math.floor(days * 864e5) + milliseconds;
5385            default:
5386                throw new Error('Unknown unit ' + units);
5387        }
5388    }
5389}
5390
5391// TODO: Use this.as('ms')?
5392function valueOf$1() {
5393    if (!this.isValid()) {
5394        return NaN;
5395    }
5396    return (
5397        this._milliseconds +
5398        this._days * 864e5 +
5399        (this._months % 12) * 2592e6 +
5400        toInt(this._months / 12) * 31536e6
5401    );
5402}
5403
5404function makeAs(alias) {
5405    return function () {
5406        return this.as(alias);
5407    };
5408}
5409
5410var asMilliseconds = makeAs('ms'),
5411    asSeconds = makeAs('s'),
5412    asMinutes = makeAs('m'),
5413    asHours = makeAs('h'),
5414    asDays = makeAs('d'),
5415    asWeeks = makeAs('w'),
5416    asMonths = makeAs('M'),
5417    asQuarters = makeAs('Q'),
5418    asYears = makeAs('y');
5419
5420function clone$1() {
5421    return createDuration(this);
5422}
5423
5424function get$2(units) {
5425    units = normalizeUnits(units);
5426    return this.isValid() ? this[units + 's']() : NaN;
5427}
5428
5429function makeGetter(name) {
5430    return function () {
5431        return this.isValid() ? this._data[name] : NaN;
5432    };
5433}
5434
5435var milliseconds = makeGetter('milliseconds'),
5436    seconds = makeGetter('seconds'),
5437    minutes = makeGetter('minutes'),
5438    hours = makeGetter('hours'),
5439    days = makeGetter('days'),
5440    months = makeGetter('months'),
5441    years = makeGetter('years');
5442
5443function weeks() {
5444    return absFloor(this.days() / 7);
5445}
5446
5447var round = Math.round,
5448    thresholds = {
5449        ss: 44, // a few seconds to seconds
5450        s: 45, // seconds to minute
5451        m: 45, // minutes to hour
5452        h: 22, // hours to day
5453        d: 26, // days to month/week
5454        w: null, // weeks to month
5455        M: 11, // months to year
5456    };
5457
5458// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
5459function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
5460    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
5461}
5462
5463function relativeTime$1(posNegDuration, withoutSuffix, thresholds, locale) {
5464    var duration = createDuration(posNegDuration).abs(),
5465        seconds = round(duration.as('s')),
5466        minutes = round(duration.as('m')),
5467        hours = round(duration.as('h')),
5468        days = round(duration.as('d')),
5469        months = round(duration.as('M')),
5470        weeks = round(duration.as('w')),
5471        years = round(duration.as('y')),
5472        a =
5473            (seconds <= thresholds.ss && ['s', seconds]) ||
5474            (seconds < thresholds.s && ['ss', seconds]) ||
5475            (minutes <= 1 && ['m']) ||
5476            (minutes < thresholds.m && ['mm', minutes]) ||
5477            (hours <= 1 && ['h']) ||
5478            (hours < thresholds.h && ['hh', hours]) ||
5479            (days <= 1 && ['d']) ||
5480            (days < thresholds.d && ['dd', days]);
5481
5482    if (thresholds.w != null) {
5483        a =
5484            a ||
5485            (weeks <= 1 && ['w']) ||
5486            (weeks < thresholds.w && ['ww', weeks]);
5487    }
5488    a = a ||
5489        (months <= 1 && ['M']) ||
5490        (months < thresholds.M && ['MM', months]) ||
5491        (years <= 1 && ['y']) || ['yy', years];
5492
5493    a[2] = withoutSuffix;
5494    a[3] = +posNegDuration > 0;
5495    a[4] = locale;
5496    return substituteTimeAgo.apply(null, a);
5497}
5498
5499// This function allows you to set the rounding function for relative time strings
5500function getSetRelativeTimeRounding(roundingFunction) {
5501    if (roundingFunction === undefined) {
5502        return round;
5503    }
5504    if (typeof roundingFunction === 'function') {
5505        round = roundingFunction;
5506        return true;
5507    }
5508    return false;
5509}
5510
5511// This function allows you to set a threshold for relative time strings
5512function getSetRelativeTimeThreshold(threshold, limit) {
5513    if (thresholds[threshold] === undefined) {
5514        return false;
5515    }
5516    if (limit === undefined) {
5517        return thresholds[threshold];
5518    }
5519    thresholds[threshold] = limit;
5520    if (threshold === 's') {
5521        thresholds.ss = limit - 1;
5522    }
5523    return true;
5524}
5525
5526function humanize(argWithSuffix, argThresholds) {
5527    if (!this.isValid()) {
5528        return this.localeData().invalidDate();
5529    }
5530
5531    var withSuffix = false,
5532        th = thresholds,
5533        locale,
5534        output;
5535
5536    if (typeof argWithSuffix === 'object') {
5537        argThresholds = argWithSuffix;
5538        argWithSuffix = false;
5539    }
5540    if (typeof argWithSuffix === 'boolean') {
5541        withSuffix = argWithSuffix;
5542    }
5543    if (typeof argThresholds === 'object') {
5544        th = Object.assign({}, thresholds, argThresholds);
5545        if (argThresholds.s != null && argThresholds.ss == null) {
5546            th.ss = argThresholds.s - 1;
5547        }
5548    }
5549
5550    locale = this.localeData();
5551    output = relativeTime$1(this, !withSuffix, th, locale);
5552
5553    if (withSuffix) {
5554        output = locale.pastFuture(+this, output);
5555    }
5556
5557    return locale.postformat(output);
5558}
5559
5560var abs$1 = Math.abs;
5561
5562function sign(x) {
5563    return (x > 0) - (x < 0) || +x;
5564}
5565
5566function toISOString$1() {
5567    // for ISO strings we do not use the normal bubbling rules:
5568    //  * milliseconds bubble up until they become hours
5569    //  * days do not bubble at all
5570    //  * months bubble up until they become years
5571    // This is because there is no context-free conversion between hours and days
5572    // (think of clock changes)
5573    // and also not between days and months (28-31 days per month)
5574    if (!this.isValid()) {
5575        return this.localeData().invalidDate();
5576    }
5577
5578    var seconds = abs$1(this._milliseconds) / 1000,
5579        days = abs$1(this._days),
5580        months = abs$1(this._months),
5581        minutes,
5582        hours,
5583        years,
5584        s,
5585        total = this.asSeconds(),
5586        totalSign,
5587        ymSign,
5588        daysSign,
5589        hmsSign;
5590
5591    if (!total) {
5592        // this is the same as C#'s (Noda) and python (isodate)...
5593        // but not other JS (goog.date)
5594        return 'P0D';
5595    }
5596
5597    // 3600 seconds -> 60 minutes -> 1 hour
5598    minutes = absFloor(seconds / 60);
5599    hours = absFloor(minutes / 60);
5600    seconds %= 60;
5601    minutes %= 60;
5602
5603    // 12 months -> 1 year
5604    years = absFloor(months / 12);
5605    months %= 12;
5606
5607    // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
5608    s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
5609
5610    totalSign = total < 0 ? '-' : '';
5611    ymSign = sign(this._months) !== sign(total) ? '-' : '';
5612    daysSign = sign(this._days) !== sign(total) ? '-' : '';
5613    hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
5614
5615    return (
5616        totalSign +
5617        'P' +
5618        (years ? ymSign + years + 'Y' : '') +
5619        (months ? ymSign + months + 'M' : '') +
5620        (days ? daysSign + days + 'D' : '') +
5621        (hours || minutes || seconds ? 'T' : '') +
5622        (hours ? hmsSign + hours + 'H' : '') +
5623        (minutes ? hmsSign + minutes + 'M' : '') +
5624        (seconds ? hmsSign + s + 'S' : '')
5625    );
5626}
5627
5628var proto$2 = Duration.prototype;
5629
5630proto$2.isValid = isValid$1;
5631proto$2.abs = abs;
5632proto$2.add = add$1;
5633proto$2.subtract = subtract$1;
5634proto$2.as = as;
5635proto$2.asMilliseconds = asMilliseconds;
5636proto$2.asSeconds = asSeconds;
5637proto$2.asMinutes = asMinutes;
5638proto$2.asHours = asHours;
5639proto$2.asDays = asDays;
5640proto$2.asWeeks = asWeeks;
5641proto$2.asMonths = asMonths;
5642proto$2.asQuarters = asQuarters;
5643proto$2.asYears = asYears;
5644proto$2.valueOf = valueOf$1;
5645proto$2._bubble = bubble;
5646proto$2.clone = clone$1;
5647proto$2.get = get$2;
5648proto$2.milliseconds = milliseconds;
5649proto$2.seconds = seconds;
5650proto$2.minutes = minutes;
5651proto$2.hours = hours;
5652proto$2.days = days;
5653proto$2.weeks = weeks;
5654proto$2.months = months;
5655proto$2.years = years;
5656proto$2.humanize = humanize;
5657proto$2.toISOString = toISOString$1;
5658proto$2.toString = toISOString$1;
5659proto$2.toJSON = toISOString$1;
5660proto$2.locale = locale;
5661proto$2.localeData = localeData;
5662
5663proto$2.toIsoString = deprecate(
5664    'toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)',
5665    toISOString$1
5666);
5667proto$2.lang = lang;
5668
5669// FORMATTING
5670
5671addFormatToken('X', 0, 0, 'unix');
5672addFormatToken('x', 0, 0, 'valueOf');
5673
5674// PARSING
5675
5676addRegexToken('x', matchSigned);
5677addRegexToken('X', matchTimestamp);
5678addParseToken('X', function (input, array, config) {
5679    config._d = new Date(parseFloat(input) * 1000);
5680});
5681addParseToken('x', function (input, array, config) {
5682    config._d = new Date(toInt(input));
5683});
5684
5685//! moment.js
5686
5687hooks.version = '2.29.
56871';
5688
5689setHookCallback(createLocal);
5690
5691hooks.fn = proto;
5692hooks.min = min;
5693hooks.max = max;
5694hooks.now = now;
5695hooks.utc = createUTC;
5696hooks.unix = createUnix;
5697hooks.months = listMonths;
5698hooks.isDate = isDate;
5699hooks.locale = getSetGlobalLocale;
5700hooks.invalid = createInvalid;
5701hooks.duration = createDuration;
5702hooks.isMoment = isMoment;
5703hooks.weekdays = listWeekdays;
5704hooks.parseZone = createInZone;
5705hooks.localeData = getLocale;
5706hooks.isDuration = isDuration;
5707hooks.monthsShort = listMonthsShort;
5708hooks.weekdaysMin = listWeekdaysMin;
5709hooks.defineLocale = defineLocale;
5710hooks.updateLocale = updateLocale;
5711hooks.locales = listLocales;
5712hooks.weekdaysShort = listWeekdaysShort;
5713hooks.normalizeUnits = normalizeUnits;
5714hooks.relativeTimeRounding = getSetRelativeTimeRounding;
5715hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
5716hooks.calendarFormat = getCalendarFormat;
5717hooks.prototype = proto;
5718
5719// currently HTML5 input type only supports 24-hour formats
5720hooks.HTML5_FMT = {
5721    DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" />
5722    DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" />
5723    DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" />
5724    DATE: 'YYYY-MM-DD', // <input type="date" />
5725    TIME: 'HH:mm', // <input type="time" />
5726    TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" />
5727    TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" />
5728    WEEK: 'GGGG-[W]WW', // <input type="week" />
5729    MONTH: 'YYYY-MM', // <input type="month" />
5730};
5731
5732/* harmony default export */ __webpack_exports__["a"] = (hooks);
5733
5734/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(160)(module)))
5735
5736/***/ }),
5737/* 1 */
5738/***/ (function(module, __webpack_exports__, __webpack_require__) {
5739
5740"use strict";
5741/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return deleteProps; });
5742/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "h", function() { return nextTick; });
5743/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "i", function() { return now; });
5744/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "f", function() { return getTranslate; });
5745/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "g", function() { return isObject; });
5746/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return extend; });
5747/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return bindModuleMethods; });
5748/* unused harmony export getComputedStyle */
5749/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return classesToSelector; });
5750/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return createElementIfNotDefined; });
5751/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
5752
5753
5754function deleteProps(obj) {
5755  var object = obj;
5756  Object.keys(object).forEach(function (key) {
5757    try {
5758      object[key] = null;
5759    } catch (e) {// no getter for object
5760    }
5761
5762    try {
5763      delete object[key];
5764    } catch (e) {// something got wrong
5765    }
5766  });
5767}
5768
5769function nextTick(callback, delay) {
5770  if (delay === void 0) {
5771    delay = 0;
5772  }
5773
5774  return setTimeout(callback, delay);
5775}
5776
5777function now() {
5778  return Date.now();
5779}
5780
5781function getComputedStyle(el) {
5782  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
5783  var style;
5784
5785  if (window.getComputedStyle) {
5786    style = window.getComputedStyle(el, null);
5787  }
5788
5789  if (!style && el.currentStyle) {
5790    style = el.currentStyle;
5791  }
5792
5793  if (!style) {
5794    style = el.style;
5795  }
5796
5797  return style;
5798}
5799
5800function getTranslate(el, axis) {
5801  if (axis === void 0) {
5802    axis = 'x';
5803  }
5804
5805  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
5806  var matrix;
5807  var curTransform;
5808  var transformMatrix;
5809  var curStyle = getComputedStyle(el, null);
5810
5811  if (window.WebKitCSSMatrix) {
5812    curTransform = curStyle.transform || curStyle.webkitTransform;
5813
5814    if (curTransform.split(',').length > 6) {
5815      curTransform = curTransform.split(', ').map(function (a) {
5816        return a.replace(',', '.');
5817      }).join(', ');
5818    } // Some old versions of Webkit choke when 'none' is passed; pass
5819    // empty string instead in this case
5820
5821
5822    transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
5823  } else {
5824    transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
5825    matrix = transformMatrix.toString().split(',');
5826  }
5827
5828  if (axis === 'x') {
5829    // Latest Chrome and webkits Fix
5830    if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41; // Crazy IE10 Matrix
5831    else if (matrix.length === 16) curTransform = parseFloat(matrix[12]); // Normal Browsers
5832      else curTransform = parseFloat(matrix[4]);
5833  }
5834
5835  if (axis === 'y') {
5836    // Latest Chrome and webkits Fix
5837    if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42; // Crazy IE10 Matrix
5838    else if (matrix.length === 16) curTransform = parseFloat(matrix[13]); // Normal Browsers
5839      else curTransform = parseFloat(matrix[5]);
5840  }
5841
5842  return curTransform || 0;
5843}
5844
5845function isObject(o) {
5846  return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === 'Object';
5847}
5848
5849function isNode(node) {
5850  // eslint-disable-next-line
5851  if (typeof window !== 'undefined' && typeof window.HTMLElement !== 'undefined') {
5852    return node instanceof HTMLElement;
5853  }
5854
5855  return node && (node.nodeType === 1 || node.nodeType === 11);
5856}
5857
5858function extend() {
5859  var to = Object(arguments.length <= 0 ? undefined : arguments[0]);
5860  var noExtend = ['__proto__', 'constructor', 'prototype'];
5861
5862  for (var i = 1; i < arguments.length; i += 1) {
5863    var nextSource = i < 0 || arguments.length <= i ? undefined : arguments[i];
5864
5865    if (nextSource !== undefined && nextSource !== null && !isNode(nextSource)) {
5866      var keysArray = Object.keys(Object(nextSource)).filter(function (key) {
5867        return noExtend.indexOf(key) < 0;
5868      });
5869
5870      for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
5871        var nextKey = keysArray[nextIndex];
5872        var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
5873
5874        if (desc !== undefined && desc.enumerable) {
5875          if (isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
5876            if (nextSource[nextKey].__swiper__) {
5877              to[nextKey] = nextSource[nextKey];
5878            } else {
5879              extend(to[nextKey], nextSource[nextKey]);
5880            }
5881          } else if (!isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
5882            to[nextKey] = {};
5883
5884            if (nextSource[nextKey].__swiper__) {
5885              to[nextKey] = nextSource[nextKey];
5886            } else {
5887              extend(to[nextKey], nextSource[nextKey]);
5888            }
5889          } else {
5890            to[nextKey] = nextSource[nextKey];
5891          }
5892        }
5893      }
5894    }
5895  }
5896
5897  return to;
5898}
5899
5900function bindModuleMethods(instance, obj) {
5901  Object.keys(obj).forEach(function (key) {
5902    if (isObject(obj[key])) {
5903      Object.keys(obj[key]).forEach(function (subKey) {
5904        if (typeof obj[key][subKey] === 'function') {
5905          obj[key][subKey] = obj[key][subKey].bind(instance);
5906        }
5907      });
5908    }
5909
5910    instance[key] = obj[key];
5911  });
5912}
5913
5914function classesToSelector(classes) {
5915  if (classes === void 0) {
5916    classes = '';
5917  }
5918
5919  return "." + classes.trim().replace(/([\.:!\/])/g, '\\$1') // eslint-disable-line
5920  .replace(/ /g, '.');
5921}
5922
5923function createElementIfNotDefined($container, params, createElements, checkProps) {
5924  var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
5925
5926  if (createElements) {
5927    Object.keys(checkProps).forEach(function (key) {
5928      if (!params[key] && params.auto === true) {
5929        var element = document.createElement('div');
5930        element.className = checkProps[key];
5931        $container.append(element);
5932        params[key] = element;
5933      }
5934    });
5935  }
5936
5937  return params;
5938}
5939
5940
5941
5942/***/ }),
5943/* 2 */
5944/***/ (function(module, exports) {
5945
5946module.exports = jQuery;
5947
5948/***/ }),
5949/* 3 */
5950/***/ (function(module, __webpack_exports__, __webpack_require__) {
5951
5952"use strict";
5953/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_dom7__ = __webpack_require__(166);
5954
5955var Methods = {
5956  addClass: __WEBPACK_IMPORTED_MODULE_0_dom7__["b" /* addClass */],
5957  removeClass: __WEBPACK_IMPORTED_MODULE_0_dom7__["D" /* removeClass */],
5958  hasClass: __WEBPACK_IMPORTED_MODULE_0_dom7__["l" /* hasClass */],
5959  toggleClass: __WEBPACK_IMPORTED_MODULE_0_dom7__["G" /* toggleClass */],
5960  attr: __WEBPACK_IMPORTED_MODULE_0_dom7__["d" /* attr */],
5961  removeAttr: __WEBPACK_IMPORTED_MODULE_0_dom7__["C" /* removeAttr */],
5962  transform: __WEBPACK_IMPORTED_MODULE_0_dom7__["H" /* transform */],
5963  transition: __WEBPACK_IMPORTED_MODULE_0_dom7__["I" /* transition */],
5964  on: __WEBPACK_IMPORTED_MODULE_0_dom7__["t" /* on */],
5965  off: __WEBPACK_IMPORTED_MODULE_0_dom7__["r" /* off */],
5966  trigger: __WEBPACK_IMPORTED_MODULE_0_dom7__["K" /* trigger */],
5967  transitionEnd: __WEBPACK_IMPORTED_MODULE_0_dom7__["J" /* transitionEnd */],
5968  outerWidth: __WEBPACK_IMPORTED_MODULE_0_dom7__["v" /* outerWidth */],
5969  outerHeight: __WEBPACK_IMPORTED_MODULE_0_dom7__["u" /* outerHeight */],
5970  styles: __WEBPACK_IMPORTED_MODULE_0_dom7__["E" /* styles */],
5971  offset: __WEBPACK_IMPORTED_MODULE_0_dom7__["s" /* offset */],
5972  css: __WEBPACK_IMPORTED_MODULE_0_dom7__["g" /* css */],
5973  each: __WEBPACK_IMPORTED_MODULE_0_dom7__["h" /* each */],
5974  html: __WEBPACK_IMPORTED_MODULE_0_dom7__["m" /* html */],
5975  text: __WEBPACK_IMPORTED_MODULE_0_dom7__["F" /* text */],
5976  is: __WEBPACK_IMPORTED_MODULE_0_dom7__["o" /* is */],
5977  index: __WEBPACK_IMPORTED_MODULE_0_dom7__["n" /* index */],
5978  eq: __WEBPACK_IMPORTED_MODULE_0_dom7__["i" /* eq */],
5979  append: __WEBPACK_IMPORTED_MODULE_0_dom7__["c" /* append */],
5980  prepend: __WEBPACK_IMPORTED_MODULE_0_dom7__["y" /* prepend */],
5981  next: __WEBPACK_IMPORTED_MODULE_0_dom7__["p" /* next */],
5982  nextAll: __WEBPACK_IMPORTED_MODULE_0_dom7__["q" /* nextAll */],
5983  prev: __WEBPACK_IMPORTED_MODULE_0_dom7__["z" /* prev */],
5984  prevAll: __WEBPACK_IMPORTED_MODULE_0_dom7__["A" /* prevAll */],
5985  parent: __WEBPACK_IMPORTED_MODULE_0_dom7__["w" /* parent */],
5986  parents: __WEBPACK_IMPORTED_MODULE_0_dom7__["x" /* parents */],
5987  closest: __WEBPACK_IMPORTED_MODULE_0_dom7__["f" /* closest */],
5988  find: __WEBPACK_IMPORTED_MODULE_0_dom7__["k" /* find */],
5989  children: __WEBPACK_IMPORTED_MODULE_0_dom7__["e" /* children */],
5990  filter: __WEBPACK_IMPORTED_MODULE_0_dom7__["j" /* filter */],
5991  remove: __WEBPACK_IMPORTED_MODULE_0_dom7__["B" /* remove */]
5992};
5993Object.keys(Methods).forEach(function (methodName) {
5994  Object.defineProperty(__WEBPACK_IMPORTED_MODULE_0_dom7__["a" /* $ */].fn, methodName, {
5995    value: Methods[methodName],
5996    writable: true
5997  });
5998});
5999/* harmony default export */ __webpack_exports__["a"] = (__WEBPACK_IMPORTED_MODULE_0_dom7__["a" /* $ */]);
6000
6001/***/ }),
6002/* 4 */
6003/***/ (function(module, __webpack_exports__, __webpack_require__) {
6004
6005"use strict";
6006/* unused harmony export extend */
6007/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return getDocument; });
6008/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return getWindow; });
6009/* unused harmony export ssrDocument */
6010/* unused harmony export ssrWindow */
6011/**
6012 * SSR Window 3.0.0
6013 * Better handling for window object in SSR environment
6014 * https://github.com/nolimits4web/ssr-window
6015 *
6016 * Copyright 2020, Vladimir Kharlampidi
6017 *
6018 * Licensed under MIT
6019 *
6020 * Released on: November 9, 2020
6021 */
6022/* eslint-disable no-param-reassign */
6023function isObject(obj) {
6024    return (obj !== null &&
6025        typeof obj === 'object' &&
6026        'constructor' in obj &&
6027        obj.constructor === Object);
6028}
6029function extend(target, src) {
6030    if (target === void 0) { target = {}; }
6031    if (src === void 0) { src = {}; }
6032    Object.keys(src).forEach(function (key) {
6033        if (typeof target[key] === 'undefined')
6034            target[key] = src[key];
6035        else if (isObject(src[key]) &&
6036            isObject(target[key]) &&
6037            Object.keys(src[key]).length > 0) {
6038            extend(target[key], src[key]);
6039        }
6040    });
6041}
6042
6043var ssrDocument = {
6044    body: {},
6045    addEventListener: function () { },
6046    removeEventListener: function () { },
6047    activeElement: {
6048        blur: function () { },
6049        nodeName: '',
6050    },
6051    querySelector: function () {
6052        return null;
6053    },
6054    querySelectorAll: function () {
6055        return [];
6056    },
6057    getElementById: function () {
6058        return null;
6059    },
6060    createEvent: function () {
6061        return {
6062            initEvent: function () { },
6063        };
6064    },
6065    createElement: function () {
6066        return {
6067            children: [],
6068            childNodes: [],
6069            style: {},
6070            setAttribute: function () { },
6071            getElementsByTagName: function () {
6072                return [];
6073            },
6074        };
6075    },
6076    createElementNS: function () {
6077        return {};
6078    },
6079    importNode: function () {
6080        return null;
6081    },
6082    location: {
6083        hash: '',
6084        host: '',
6085        hostname: '',
6086        href: '',
6087        origin: '',
6088        pathname: '',
6089        protocol: '',
6090        search: '',
6091    },
6092};
6093function getDocument() {
6094    var doc = typeof document !== 'undefined' ? document : {};
6095    extend(doc, ssrDocument);
6096    return doc;
6097}
6098
6099var ssrWindow = {
6100    document: ssrDocument,
6101    navigator: {
6102        userAgent: '',
6103    },
6104    location: {
6105        hash: '',
6106        host: '',
6107        hostname: '',
6108        href: '',
6109        origin: '',
6110        pathname: '',
6111        protocol: '',
6112        search: '',
6113    },
6114    history: {
6115        replaceState: function () { },
6116        pushState: function () { },
6117        go: function () { },
6118        back: function () { },
6119    },
6120    CustomEvent: function CustomEvent() {
6121        return this;
6122    },
6123    addEventListener: function () { },
6124    removeEventListener: function () { },
6125    getComputedStyle: function () {
6126        return {
6127            getPropertyValue: function () {
6128                return '';
6129            },
6130        };
6131    },
6132    Image: function () { },
6133    Date: function () { },
6134    screen: {},
6135    setTimeout: function () { },
6136    clearTimeout: function () { },
6137    matchMedia: function () {
6138        return {};
6139    },
6140    requestAnimationFrame: function (callback) {
6141        if (typeof setTimeout === 'undefined') {
6142            callback();
6143            return null;
6144        }
6145        return setTimeout(callback, 0);
6146    },
6147    cancelAnimationFrame: function (id) {
6148        if (typeof setTimeout === 'undefined') {
6149            return;
6150        }
6151        clearTimeout(id);
6152    },
6153};
6154function getWindow() {
6155    var win = typeof window !== 'undefined' ? window : {};
6156    extend(win, ssrWindow);
6157    return win;
6158}
6159
6160
6161
6162
6163/***/ }),
6164/* 5 */
6165/***/ (function(module, exports, __webpack_require__) {
6166
6167var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
6168	"use strict";
6169
6170	if ( true ) {
6171
6172		// AMD. Register as an anonymous module.
6173		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
6174				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
6175				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
6176				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
6177	} else {
6178
6179		// Browser globals
6180		factory( jQuery );
6181	}
6182} )( function( $ ) {
6183"use strict";
6184
6185$.ui = $.ui || {};
6186
6187return $.ui.version = "1.13.0";
6188
6189} );
6190
6191
6192/***/ }),
6193/* 6 */
6194/***/ (function(module, __webpack_exports__, __webpack_require__) {
6195
6196"use strict";
6197/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__esm_components_core_core_class__ = __webpack_require__(145);
6198/* unused harmony reexport Swiper */
6199/* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return __WEBPACK_IMPORTED_MODULE_0__esm_components_core_core_class__["a"]; });
6200/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__esm_components_virtual_virtual__ = __webpack_require__(232);
6201/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__esm_components_keyboard_keyboard__ = __webpack_require__(233);
6202/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__esm_components_mousewheel_mousewheel__ = __webpack_require__(234);
6203/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__esm_components_navigation_navigation__ = __webpack_require__(235);
6204/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__esm_components_pagination_pagination__ = __webpack_require__(236);
6205/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__esm_components_scrollbar_scrollbar__ = __webpack_require__(237);
6206/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__esm_components_parallax_parallax__ = __webpack_require__(238);
6207/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__esm_components_zoom_zoom__ = __webpack_require__(239);
6208/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__esm_components_lazy_lazy__ = __webpack_require__(240);
6209/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__esm_components_controller_controller__ = __webpack_require__(241);
6210/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__esm_components_a11y_a11y__ = __webpack_require__(242);
6211/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__esm_components_history_history__ = __webpack_require__(243);
6212/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__esm_components_hash_navigation_hash_n
6212avigation__ = __webpack_require__(244);
6213/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__esm_components_autoplay_autoplay__ = __webpack_require__(245);
6214/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__esm_components_effect_fade_effect_fade__ = __webpack_require__(246);
6215/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__esm_components_effect_cube_effect_cube__ = __webpack_require__(247);
6216/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__esm_components_effect_flip_effect_flip__ = __webpack_require__(248);
6217/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__esm_components_effect_coverflow_effect_coverflow__ = __webpack_require__(249);
6218/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__esm_components_thumbs_thumbs__ = __webpack_require__(250);
6219/**
6220 * Swiper 6.8.4
6221 * Most modern mobile touch slider and framework with hardware accelerated transitions
6222 * https://swiperjs.com
6223 *
6224 * Copyright 2014-2021 Vladimir Kharlampidi
6225 *
6226 * Released under the MIT License
6227 *
6228 * Released on: August 23, 2021
6229 */
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253// Swiper Class
6254var components = [__WEBPACK_IMPORTED_MODULE_1__esm_components_virtual_virtual__["a" /* default */], __WEBPACK_IMPORTED_MODULE_2__esm_components_keyboard_keyboard__["a" /* default */], __WEBPACK_IMPORTED_MODULE_3__esm_components_mousewheel_mousewheel__["a" /* default */], __WEBPACK_IMPORTED_MODULE_4__esm_components_navigation_navigation__["a" /* default */], __WEBPACK_IMPORTED_MODULE_5__esm_components_pagination_pagination__["a" /* default */], __WEBPACK_IMPORTED_MODULE_6__esm_components_scrollbar_scrollbar__["a" /* default */], __WEBPACK_IMPORTED_MODULE_7__esm_components_parallax_parallax__["a" /* default */], __WEBPACK_IMPORTED_MODULE_8__esm_components_zoom_zoom__["a" /* default */], __WEBPACK_IMPORTED_MODULE_9__esm_components_lazy_lazy__["a" /* default */], __WEBPACK_IMPORTED_MODULE_10__esm_components_controller_controller__["a" /* default */], __WEBPACK_IMPORTED_MODULE_11__esm_components_a11y_a11y__["a" /* default */], __WEBPACK_IMPORTED_MODULE_12__esm_components_history_history__["a" /* default */], __WEBPACK_IMPORTED_MODULE_13__esm_components_hash_navigation_hash_navigation__["a" /* default */], __WEBPACK_IMPORTED_MODULE_14__esm_components_autoplay_autoplay__["a" /* default */], __WEBPACK_IMPORTED_MODULE_15__esm_components_effect_fade_effect_fade__["a" /* default */], __WEBPACK_IMPORTED_MODULE_16__esm_components_effect_cube_effect_cube__["a" /* default */], __WEBPACK_IMPORTED_MODULE_17__esm_components_effect_flip_effect_flip__["a" /* default */], __WEBPACK_IMPORTED_MODULE_18__esm_components_effect_coverflow_effect_coverflow__["a" /* default */], __WEBPACK_IMPORTED_MODULE_19__esm_components_thumbs_thumbs__["a" /* default */]];
6255__WEBPACK_IMPORTED_MODULE_0__esm_components_core_core_class__["a" /* default */].use(components);
6256
6257
6258/***/ }),
6259/* 7 */
6260/***/ (function(module, exports, __webpack_require__) {
6261
6262var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
6263 * Masonry v4.2.2
6264 * Cascading grid layout library
6265 * https://masonry.desandro.com
6266 * MIT License
6267 * by David DeSandro
6268 */
6269
6270( function( window, factory ) {
6271  // universal module definition
6272  /* jshint strict: false */ /*globals define, module, require */
6273  if ( true ) {
6274    // AMD
6275    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
6276        __webpack_require__(156),
6277        __webpack_require__(9)
6278      ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
6279				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
6280				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
6281				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
6282  } else if ( typeof module == 'object' && module.exports ) {
6283    // CommonJS
6284    module.exports = factory(
6285      require('outlayer'),
6286      require('get-size')
6287    );
6288  } else {
6289    // browser global
6290    window.Masonry = factory(
6291      window.Outlayer,
6292      window.getSize
6293    );
6294  }
6295
6296}( window, function factory( Outlayer, getSize ) {
6297
6298'use strict';
6299
6300// -------------------------- masonryDefinition -------------------------- //
6301
6302  // create an Outlayer layout class
6303  var Masonry = Outlayer.create('masonry');
6304  // isFitWidth -> fitWidth
vendor: 7,214 bytes, lines 6305-6525
6305  Masonry.compatOptions.fitWidth = 'isFitWidth';
6306
6307  var proto = Masonry.prototype;
6308
6309  proto._resetLayout = function() {
6310    this.getSize();
6311    this._getMeasurement( 'columnWidth', 'outerWidth' );
6312    this._getMeasurement( 'gutter', 'outerWidth' );
6313    this.measureColumns();
6314
6315    // reset column Y
6316    this.colYs = [];
6317    for ( var i=0; i < this.cols; i++ ) {
6318      this.colYs.push( 0 );
6319    }
6320
6321    this.maxY = 0;
6322    this.horizontalColIndex = 0;
6323  };
6324
6325  proto.measureColumns = function() {
6326    this.getContainerWidth();
6327    // if columnWidth is 0, default to outerWidth of first item
6328    if ( !this.columnWidth ) {
6329      var firstItem = this.items[0];
6330      var firstItemElem = firstItem && firstItem.element;
6331      // columnWidth fall back to item of first element
6332      this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
6333        // if first elem has no width, default to size of container
6334        this.containerWidth;
6335    }
6336
6337    var columnWidth = this.columnWidth += this.gutter;
6338
6339    // calculate columns
6340    var containerWidth = this.containerWidth + this.gutter;
6341    var cols = containerWidth / columnWidth;
6342    // fix rounding errors, typically with gutters
6343    var excess = columnWidth - containerWidth % columnWidth;
6344    // if overshoot is less than a pixel, round up, otherwise floor it
6345    var mathMethod = excess && excess < 1 ? 'round' : 'floor';
6346    cols = Math[ mathMethod ]( cols );
6347    this.cols = Math.max( cols, 1 );
6348  };
6349
6350  proto.getContainerWidth = function() {
6351    // container is parent if fit width
6352    var isFitWidth = this._getOption('fitWidth');
6353    var container = isFitWidth ? this.element.parentNode : this.element;
6354    // check that this.size and size are there
6355    // IE8 triggers resize on body size change, so they might not be
6356    var size = getSize( container );
6357    this.containerWidth = size && size.innerWidth;
6358  };
6359
6360  proto._getItemLayoutPosition = function( item ) {
6361    item.getSize();
6362    // how many columns does this brick span
6363    var remainder = item.size.outerWidth % this.columnWidth;
6364    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
6365    // round if off by 1 pixel, otherwise use ceil
6366    var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
6367    colSpan = Math.min( colSpan, this.cols );
6368    // use horizontal or top column position
6369    var colPosMethod = this.options.horizontalOrder ?
6370      '_getHorizontalColPosition' : '_getTopColPosition';
6371    var colPosition = this[ colPosMethod ]( colSpan, item );
6372    // position the brick
6373    var position = {
6374      x: this.columnWidth * colPosition.col,
6375      y: colPosition.y
6376    };
6377    // apply setHeight to necessary columns
6378    var setHeight = colPosition.y + item.size.outerHeight;
6379    var setMax = colSpan + colPosition.col;
6380    for ( var i = colPosition.col; i < setMax; i++ ) {
6381      this.colYs[i] = setHeight;
6382    }
6383
6384    return position;
6385  };
6386
6387  proto._getTopColPosition = function( colSpan ) {
6388    var colGroup = this._getTopColGroup( colSpan );
6389    // get the minimum Y value from the columns
6390    var minimumY = Math.min.apply( Math, colGroup );
6391
6392    return {
6393      col: colGroup.indexOf( minimumY ),
6394      y: minimumY,
6395    };
6396  };
6397
6398  /**
6399   * @param {Number} colSpan - number of columns the element spans
6400   * @returns {Array} colGroup
6401   */
6402  proto._getTopColGroup = function( colSpan ) {
6403    if ( colSpan < 2 ) {
6404      // if brick spans only one column, use all the column Ys
6405      return this.colYs;
6406    }
6407
6408    var colGroup = [];
6409    // how many different places could this brick fit horizontally
6410    var groupCount = this.cols + 1 - colSpan;
6411    // for each group potential horizontal position
6412    for ( var i = 0; i < groupCount; i++ ) {
6413      colGroup[i] = this._getColGroupY( i, colSpan );
6414    }
6415    return colGroup;
6416  };
6417
6418  proto._getColGroupY = function( col, colSpan ) {
6419    if ( colSpan < 2 ) {
6420      return this.colYs[ col ];
6421    }
6422    // make an array of colY values for that one group
6423    var groupColYs = this.colYs.slice( col, col + colSpan );
6424    // and get the max value of the array
6425    return Math.max.apply( Math, groupColYs );
6426  };
6427
6428  // get column position based on horizontal index. #873
6429  proto._getHorizontalColPosition = function( colSpan, item ) {
6430    var col = this.horizontalColIndex % this.cols;
6431    var isOver = colSpan > 1 && col + colSpan > this.cols;
6432    // shift to next row if item can't fit on current row
6433    col = isOver ? 0 : col;
6434    // don't let zero-size items take up space
6435    var hasSize = item.size.outerWidth && item.size.outerHeight;
6436    this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex;
6437
6438    return {
6439      col: col,
6440      y: this._getColGroupY( col, colSpan ),
6441    };
6442  };
6443
6444  proto._manageStamp = function( stamp ) {
6445    var stampSize = getSize( stamp );
6446    var offset = this._getElementOffset( stamp );
6447    // get the columns that this stamp affects
6448    var isOriginLeft = this._getOption('originLeft');
6449    var firstX = isOriginLeft ? offset.left : offset.right;
6450    var lastX = firstX + stampSize.outerWidth;
6451    var firstCol = Math.floor( firstX / this.columnWidth );
6452    firstCol = Math.max( 0, firstCol );
6453    var lastCol = Math.floor( lastX / this.columnWidth );
6454    // lastCol should not go over if multiple of columnWidth #425
6455    lastCol -= lastX % this.columnWidth ? 0 : 1;
6456    lastCol = Math.min( this.cols - 1, lastCol );
6457    // set colYs to bottom of the stamp
6458
6459    var isOriginTop = this._getOption('originTop');
6460    var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +
6461      stampSize.outerHeight;
6462    for ( var i = firstCol; i <= lastCol; i++ ) {
6463      this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
6464    }
6465  };
6466
6467  proto._getContainerSize = function() {
6468    this.maxY = Math.max.apply( Math, this.colYs );
6469    var size = {
6470      height: this.maxY
6471    };
6472
6473    if ( this._getOption('fitWidth') ) {
6474      size.width = this._getContainerFitWidth();
6475    }
6476
6477    return size;
6478  };
6479
6480  proto._getContainerFitWidth = function() {
6481    var unusedCols = 0;
6482    // count unused columns
6483    var i = this.cols;
6484    while ( --i ) {
6485      if ( this.colYs[i] !== 0 ) {
6486        break;
6487      }
6488      unusedCols++;
6489    }
6490    // fit container to columns that have been used
6491    return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
6492  };
6493
6494  proto.needsResizeLayout = function() {
6495    var previousWidth = this.containerWidth;
6496    this.getContainerWidth();
6497    return previousWidth != this.containerWidth;
6498  };
6499
6500  return Masonry;
6501
6502}));
6503
6504
6505/***/ }),
6506/* 8 */
6507/***/ (function(module, exports, __webpack_require__) {
6508
6509var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
6510 * EvEmitter v1.1.0
6511 * Lil' event emitter
6512 * MIT License
6513 */
6514
6515/* jshint unused: true, undef: true, strict: true */
6516
6517( function( global, factory ) {
6518  // universal module definition
6519  /* jshint strict: false */ /* globals define, module, window */
6520  if ( true ) {
6521    // AMD - RequireJS
6522    !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
6523				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
6524				(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :
6525				__WEBPACK_AMD_DEFINE_FACTORY__),
vendor: 5,131 bytes, lines 6526-6730
6526				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
6527  } else if ( typeof module == 'object' && module.exports ) {
6528    // CommonJS - Browserify, Webpack
6529    module.exports = factory();
6530  } else {
6531    // Browser globals
6532    global.EvEmitter = factory();
6533  }
6534
6535}( typeof window != 'undefined' ? window : this, function() {
6536
6537"use strict";
6538
6539function EvEmitter() {}
6540
6541var proto = EvEmitter.prototype;
6542
6543proto.on = function( eventName, listener ) {
6544  if ( !eventName || !listener ) {
6545    return;
6546  }
6547  // set events hash
6548  var events = this._events = this._events || {};
6549  // set listeners array
6550  var listeners = events[ eventName ] = events[ eventName ] || [];
6551  // only add once
6552  if ( listeners.indexOf( listener ) == -1 ) {
6553    listeners.push( listener );
6554  }
6555
6556  return this;
6557};
6558
6559proto.once = function( eventName, listener ) {
6560  if ( !eventName || !listener ) {
6561    return;
6562  }
6563  // add event
6564  this.on( eventName, listener );
6565  // set once flag
6566  // set onceEvents hash
6567  var onceEvents = this._onceEvents = this._onceEvents || {};
6568  // set onceListeners object
6569  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
6570  // set flag
6571  onceListeners[ listener ] = true;
6572
6573  return this;
6574};
6575
6576proto.off = function( eventName, listener ) {
6577  var listeners = this._events && this._events[ eventName ];
6578  if ( !listeners || !listeners.length ) {
6579    return;
6580  }
6581  var index = listeners.indexOf( listener );
6582  if ( index != -1 ) {
6583    listeners.splice( index, 1 );
6584  }
6585
6586  return this;
6587};
6588
6589proto.emitEvent = function( eventName, args ) {
6590  var listeners = this._events && this._events[ eventName ];
6591  if ( !listeners || !listeners.length ) {
6592    return;
6593  }
6594  // copy over to avoid interference if .off() in listener
6595  listeners = listeners.slice(0);
6596  args = args || [];
6597  // once stuff
6598  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
6599
6600  for ( var i=0; i < listeners.length; i++ ) {
6601    var listener = listeners[i]
6602    var isOnce = onceListeners && onceListeners[ listener ];
6603    if ( isOnce ) {
6604      // remove listener
6605      // remove before trigger to prevent recursion
6606      this.off( eventName, listener );
6607      // unset once flag
6608      delete onceListeners[ listener ];
6609    }
6610    // trigger listener
6611    listener.apply( this, args );
6612  }
6613
6614  return this;
6615};
6616
6617proto.allOff = function() {
6618  delete this._events;
6619  delete this._onceEvents;
6620};
6621
6622return EvEmitter;
6623
6624}));
6625
6626
6627/***/ }),
6628/* 9 */
6629/***/ (function(module, exports, __webpack_require__) {
6630
6631var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
6632 * getSize v2.0.3
6633 * measure size of elements
6634 * MIT license
6635 */
6636
6637/* jshint browser: true, strict: true, undef: true, unused: true */
6638/* globals console: false */
6639
6640( function( window, factory ) {
6641  /* jshint strict: false */ /* globals define, module */
6642  if ( true ) {
6643    // AMD
6644    !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
6645				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
6646				(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :
6647				__WEBPACK_AMD_DEFINE_FACTORY__),
6648				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
6649  } else if ( typeof module == 'object' && module.exports ) {
6650    // CommonJS
6651    module.exports = factory();
6652  } else {
6653    // browser global
6654    window.getSize = factory();
6655  }
6656
6657})( window, function factory() {
6658'use strict';
6659
6660// -------------------------- helpers -------------------------- //
6661
6662// get a number from a string, not a percentage
6663function getStyleSize( value ) {
6664  var num = parseFloat( value );
6665  // not a percent like '100%', and a number
6666  var isValid = value.indexOf('%') == -1 && !isNaN( num );
6667  return isValid && num;
6668}
6669
6670function noop() {}
6671
6672var logError = typeof console == 'undefined' ? noop :
6673  function( message ) {
6674    console.error( message );
6675  };
6676
6677// -------------------------- measurements -------------------------- //
6678
6679var measurements = [
6680  'paddingLeft',
6681  'paddingRight',
6682  'paddingTop',
6683  'paddingBottom',
6684  'marginLeft',
6685  'marginRight',
6686  'marginTop',
6687  'marginBottom',
6688  'borderLeftWidth',
6689  'borderRightWidth',
6690  'borderTopWidth',
6691  'borderBottomWidth'
6692];
6693
6694var measurementsLength = measurements.length;
6695
6696function getZeroSize() {
6697  var size = {
6698    width: 0,
6699    height: 0,
6700    innerWidth: 0,
6701    innerHeight: 0,
6702    outerWidth: 0,
6703    outerHeight: 0
6704  };
6705  for ( var i=0; i < measurementsLength; i++ ) {
6706    var measurement = measurements[i];
6707    size[ measurement ] = 0;
6708  }
6709  return size;
6710}
6711
6712// -------------------------- getStyle -------------------------- //
6713
6714/**
6715 * getStyle, get style of element, check for Firefox bug
6716 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
6717 */
6718function getStyle( elem ) {
6719  var style = getComputedStyle( elem );
6720  if ( !style ) {
6721    logError( 'Style returned ' + style +
6722      '. Are you running this code in a hidden iframe on Firefox? ' +
6723      'See https://bit.ly/getsizebug1' );
6724  }
6725  return style;
6726}
6727
6728// -------------------------- setup -------------------------- //
6729
6730var isSetup = false;
vendor: 4,855 bytes, lines 6731-6894
6731
6732var isBoxSizeOuter;
6733
6734/**
6735 * setup
6736 * check isBoxSizerOuter
6737 * do on first getSize() rather than on page load for Firefox bug
6738 */
6739function setup() {
6740  // setup once
6741  if ( isSetup ) {
6742    return;
6743  }
6744  isSetup = true;
6745
6746  // -------------------------- box sizing -------------------------- //
6747
6748  /**
6749   * Chrome & Safari measure the outer-width on style.width on border-box elems
6750   * IE11 & Firefox<29 measures the inner-width
6751   */
6752  var div = document.createElement('div');
6753  div.style.width = '200px';
6754  div.style.padding = '1px 2px 3px 4px';
6755  div.style.borderStyle = 'solid';
6756  div.style.borderWidth = '1px 2px 3px 4px';
6757  div.style.boxSizing = 'border-box';
6758
6759  var body = document.body || document.documentElement;
6760  body.appendChild( div );
6761  var style = getStyle( div );
6762  // round value for browser zoom. desandro/masonry#928
6763  isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200;
6764  getSize.isBoxSizeOuter = isBoxSizeOuter;
6765
6766  body.removeChild( div );
6767}
6768
6769// -------------------------- getSize -------------------------- //
6770
6771function getSize( elem ) {
6772  setup();
6773
6774  // use querySeletor if elem is string
6775  if ( typeof elem == 'string' ) {
6776    elem = document.querySelector( elem );
6777  }
6778
6779  // do not proceed on non-objects
6780  if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
6781    return;
6782  }
6783
6784  var style = getStyle( elem );
6785
6786  // if hidden, everything is 0
6787  if ( style.display == 'none' ) {
6788    return getZeroSize();
6789  }
6790
6791  var size = {};
6792  size.width = elem.offsetWidth;
6793  size.height = elem.offsetHeight;
6794
6795  var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
6796
6797  // get all measurements
6798  for ( var i=0; i < measurementsLength; i++ ) {
6799    var measurement = measurements[i];
6800    var value = style[ measurement ];
6801    var num = parseFloat( value );
6802    // any 'auto', 'medium' value will be 0
6803    size[ measurement ] = !isNaN( num ) ? num : 0;
6804  }
6805
6806  var paddingWidth = size.paddingLeft + size.paddingRight;
6807  var paddingHeight = size.paddingTop + size.paddingBottom;
6808  var marginWidth = size.marginLeft + size.marginRight;
6809  var marginHeight = size.marginTop + size.marginBottom;
6810  var borderWidth = size.borderLeftWidth + size.borderRightWidth;
6811  var borderHeight = size.borderTopWidth + size.borderBottomWidth;
6812
6813  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
6814
6815  // overwrite width and height if we can get it from style
6816  var styleWidth = getStyleSize( style.width );
6817  if ( styleWidth !== false ) {
6818    size.width = styleWidth +
6819      // add padding and border unless it's already including it
6820      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
6821  }
6822
6823  var styleHeight = getStyleSize( style.height );
6824  if ( styleHeight !== false ) {
6825    size.height = styleHeight +
6826      // add padding and border unless it's already including it
6827      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
6828  }
6829
6830  size.innerWidth = size.width - ( paddingWidth + borderWidth );
6831  size.innerHeight = size.height - ( paddingHeight + borderHeight );
6832
6833  size.outerWidth = size.width + marginWidth;
6834  size.outerHeight = size.height + marginHeight;
6835
6836  return size;
6837}
6838
6839return getSize;
6840
6841});
6842
6843
6844/***/ }),
6845/* 10 */
6846/***/ (function(module, __webpack_exports__, __webpack_require__) {
6847
6848"use strict";
6849Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
6850/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
6851//! moment.js locale configuration
6852//! locale : Afrikaans [af]
6853//! author : Werner Mollentze : https://github.com/wernerm
6854
6855
6856
6857/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('af', {
6858    months: 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split(
6859        '_'
6860    ),
6861    monthsShort: 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),
6862    weekdays: 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split(
6863        '_'
6864    ),
6865    weekdaysShort: 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),
6866    weekdaysMin: 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),
6867    meridiemParse: /vm|nm/i,
6868    isPM: function (input) {
6869        return /^nm$/i.test(input);
6870    },
6871    meridiem: function (hours, minutes, isLower) {
6872        if (hours < 12) {
6873            return isLower ? 'vm' : 'VM';
6874        } else {
6875            return isLower ? 'nm' : 'NM';
6876        }
6877    },
6878    longDateFormat: {
6879        LT: 'HH:mm',
6880        LTS: 'HH:mm:ss',
6881        L: 'DD/MM/YYYY',
6882        LL: 'D MMMM YYYY',
6883        LLL: 'D MMMM YYYY HH:mm',
6884        LLLL: 'dddd, D MMMM YYYY HH:mm',
6885    },
6886    calendar: {
6887        sameDay: '[Vandag om] LT',
6888        nextDay: '[Môre om] LT',
6889        nextWeek: 'dddd [om] LT',
6890        lastDay: '[Gister om] LT',
6891        lastWeek: '[Laas] dddd [om] LT',
6892        sameElse: 'L',
6893    },
6894    relativeTime: {
vendor: 16,384 bytes, lines 6895-7466
6895        future: 'oor %s',
6896        past: '%s gelede',
6897        s: "'n paar sekondes",
6898        ss: '%d sekondes',
6899        m: "'n minuut",
6900        mm: '%d minute',
6901        h: "'n uur",
6902        hh: '%d ure',
6903        d: "'n dag",
6904        dd: '%d dae',
6905        M: "'n maand",
6906        MM: '%d maande',
6907        y: "'n jaar",
6908        yy: '%d jaar',
6909    },
6910    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
6911    ordinal: function (number) {
6912        return (
6913            number +
6914            (number === 1 || number === 8 || number >= 20 ? 'ste' : 'de')
6915        ); // Thanks to Joris Röling : https://github.com/jjupiter
6916    },
6917    week: {
6918        dow: 1, // Maandag is die eerste dag van die week.
6919        doy: 4, // Die week wat die 4de Januarie bevat is die eerste week van die jaar.
6920    },
6921}));
6922
6923
6924/***/ }),
6925/* 11 */
6926/***/ (function(module, __webpack_exports__, __webpack_require__) {
6927
6928"use strict";
6929Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
6930/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
6931//! moment.js locale configuration
6932//! locale : Arabic [ar]
6933//! author : Abdel Said: https://github.com/abdelsaid
6934//! author : Ahmed Elkhatib
6935//! author : forabi https://github.com/forabi
6936
6937
6938
6939var symbolMap = {
6940        1: 'Ù¡',
6941        2: 'Ù¢',
6942        3: 'Ù£',
6943        4: 'Ù¤',
6944        5: 'Ù¥',
6945        6: 'Ù¦',
6946        7: 'Ù§',
6947        8: 'Ù¨',
6948        9: 'Ù©',
6949        0: 'Ù ',
6950    },
6951    numberMap = {
6952        'Ù¡': '1',
6953        'Ù¢': '2',
6954        'Ù£': '3',
6955        'Ù¤': '4',
6956        'Ù¥': '5',
6957        'Ù¦': '6',
6958        'Ù§': '7',
6959        'Ù¨': '8',
6960        'Ù©': '9',
6961        'Ù ': '0',
6962    },
6963    pluralForm = function (n) {
6964        return n === 0
6965            ? 0
6966            : n === 1
6967            ? 1
6968            : n === 2
6969            ? 2
6970            : n % 100 >= 3 && n % 100 <= 10
6971            ? 3
6972            : n % 100 >= 11
6973            ? 4
6974            : 5;
6975    },
6976    plurals = {
6977        s: [
6978            'أقل من ثانية',
6979            'ثانية واحدة',
6980            ['ثانيتان', 'ثانيتين'],
6981            '%d ثوان',
6982            '%d ثانية',
6983            '%d ثانية',
6984        ],
6985        m: [
6986            'أقل من دقيقة',
6987            'دقيقة واحدة',
6988            ['دقيقتان', 'دقيقتين'],
6989            '%d دقائق',
6990            '%d دقيقة',
6991            '%d دقيقة',
6992        ],
6993        h: [
6994            'أقل من ساعة',
6995            'ساعة واحدة',
6996            ['ساعتان', 'ساعتين'],
6997            '%d ساعات',
6998            '%d ساعة',
6999            '%d ساعة',
7000        ],
7001        d: [
7002            'أقل من يوم',
7003            'يوم واحد',
7004            ['يومان', 'يومين'],
7005            '%d أيام',
7006            '%d يومًا',
7007            '%d يوم',
7008        ],
7009        M: [
7010            'أقل من شهر',
7011            'شهر واحد',
7012            ['شهران', 'شهرين'],
7013            '%d أشهر',
7014            '%d شهرا',
7015            '%d شهر',
7016        ],
7017        y: [
7018            'أقل من عام',
7019            'عام واحد',
7020            ['عامان', 'عامين'],
7021            '%d أعوام',
7022            '%d عامًا',
7023            '%d عام',
7024        ],
7025    },
7026    pluralize = function (u) {
7027        return function (number, withoutSuffix, string, isFuture) {
7028            var f = pluralForm(number),
7029                str = plurals[u][pluralForm(number)];
7030            if (f === 2) {
7031                str = str[withoutSuffix ? 0 : 1];
7032            }
7033            return str.replace(/%d/i, number);
7034        };
7035    },
7036    months = [
7037        'يناير',
7038        'فبراير',
7039        'مارس',
7040        'أبريل',
7041        'مايو',
7042        'يونيو',
7043        'يوليو',
7044        'أغسطس',
7045        'سبتمبر',
7046        'أكتوبر',
7047        'نوفمبر',
7048        'ديسمبر',
7049    ];
7050
7051/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ar', {
7052    months: months,
7053    monthsShort: months,
7054    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
7055    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
7056    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
7057    weekdaysParseExact: true,
7058    longDateFormat: {
7059        LT: 'HH:mm',
7060        LTS: 'HH:mm:ss',
7061        L: 'D/\u200FM/\u200FYYYY',
7062        LL: 'D MMMM YYYY',
7063        LLL: 'D MMMM YYYY HH:mm',
7064        LLLL: 'dddd D MMMM YYYY HH:mm',
7065    },
7066    meridiemParse: /ص|م/,
7067    isPM: function (input) {
7068        return 'م' === input;
7069    },
7070    meridiem: function (hour, minute, isLower) {
7071        if (hour < 12) {
7072            return 'ص';
7073        } else {
7074            return 'م';
7075        }
7076    },
7077    calendar: {
7078        sameDay: '[اليوم عند الساعة] LT',
7079        nextDay: '[غدًا عند الساعة] LT',
7080        nextWeek: 'dddd [عند الساعة] LT',
7081        lastDay: '[أمس عند الساعة] LT',
7082        lastWeek: 'dddd [عند الساعة] LT',
7083        sameElse: 'L',
7084    },
7085    relativeTime: {
7086        future: 'بعد %s',
7087        past: 'منذ %s',
7088        s: pluralize('s'),
7089        ss: pluralize('s'),
7090        m: pluralize('m'),
7091        mm: pluralize('m'),
7092        h: pluralize('h'),
7093        hh: pluralize('h'),
7094        d: pluralize('d'),
7095        dd: pluralize('d'),
7096        M: pluralize('M'),
7097        MM: pluralize('M'),
7098        y: pluralize('y'),
7099        yy: pluralize('y'),
7100    },
7101    preparse: function (string) {
7102        return string
7103            .replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
7104                return numberMap[match];
7105            })
7106            .replace(/،/g, ',');
7107    },
7108    postformat: function (string) {
7109        return string
7110            .replace(/\d/g, function (match) {
7111                return symbolMap[match];
7112            })
7113            .replace(/,/g, '،');
7114    },
7115    week: {
7116        dow: 6, // Saturday is the first day of the week.
7117        doy: 12, // The week that contains Jan 12th is the first week of the year.
7118    },
7119}));
7120
7121
7122/***/ }),
7123/* 12 */
7124/***/ (function(module, __webpack_exports__, __webpack_require__) {
7125
7126"use strict";
7127Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
7128/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
7129//! moment.js locale configuration
7130//! locale : Arabic (Algeria) [ar-dz]
7131//! author : Amine Roukh: https://github.com/Amine27
7132//! author : Abdel Said: https://github.com/abdelsaid
7133//! author : Ahmed Elkhatib
7134//! author : forabi https://github.com/forabi
7135//! author : Noureddine LOUAHEDJ : https://github.com/noureddinem
7136
7137
7138
7139var pluralForm = function (n) {
7140        return n === 0
7141            ? 0
7142            : n === 1
7143            ? 1
7144            : n === 2
7145            ? 2
7146            : n % 100 >= 3 && n % 100 <= 10
7147            ? 3
7148            : n % 100 >= 11
7149            ? 4
7150            : 5;
7151    },
7152    plurals = {
7153        s: [
7154            'أقل من ثانية',
7155            'ثانية واحدة',
7156            ['ثانيتان', 'ثانيتين'],
7157            '%d ثوان',
7158            '%d ثانية',
7159            '%d ثانية',
7160        ],
7161        m: [
7162            'أقل من دقيقة',
7163            'دقيقة واحدة',
7164            ['دقيقتان', 'دقيقتين'],
7165            '%d دقائق',
7166            '%d دقيقة',
7167            '%d دقيقة',
7168        ],
7169        h: [
7170            'أقل من ساعة',
7171            'ساعة واحدة',
7172            ['ساعتان', 'ساعتين'],
7173            '%d ساعات',
7174            '%d ساعة',
7175            '%d ساعة',
7176        ],
7177        d: [
7178            'أقل من يوم',
7179            'يوم واحد',
7180            ['يومان', 'يومين'],
7181            '%d أيام',
7182            '%d يومًا',
7183            '%d يوم',
7184        ],
7185        M: [
7186            'أقل من شهر',
7187            'شهر واحد',
7188            ['شهران', 'شهرين'],
7189            '%d أشهر',
7190            '%d شهرا',
7191            '%d شهر',
7192        ],
7193        y: [
7194            'أقل من عام',
7195            'عام واحد',
7196            ['عامان', 'عامين'],
7197            '%d أعوام',
7198            '%d عامًا',
7199            '%d عام',
7200        ],
7201    },
7202    pluralize = function (u) {
7203        return function (number, withoutSuffix, string, isFuture) {
7204            var f = pluralForm(number),
7205                str = plurals[u][pluralForm(number)];
7206            if (f === 2) {
7207                str = str[withoutSuffix ? 0 : 1];
7208            }
7209            return str.replace(/%d/i, number);
7210        };
7211    },
7212    months = [
7213        'جانفي',
7214        'فيفري',
7215        'مارس',
7216        'أفريل',
7217        'ماي',
7218        'جوان',
7219        'جويلية',
7220        'أوت',
7221        'سبتمبر',
7222        'أكتوبر',
7223        'نوفمبر',
7224        'ديسمبر',
7225    ];
7226
7227/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ar-dz', {
7228    months: months,
7229    monthsShort: months,
7230    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
7231    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
7232    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
7233    weekdaysParseExact: true,
7234    longDateFormat: {
7235        LT: 'HH:mm',
7236        LTS: 'HH:mm:ss',
7237        L: 'D/\u200FM/\u200FYYYY',
7238        LL: 'D MMMM YYYY',
7239        LLL: 'D MMMM YYYY HH:mm',
7240        LLLL: 'dddd D MMMM YYYY HH:mm',
7241    },
7242    meridiemParse: /ص|م/,
7243    isPM: function (input) {
7244        return 'م' === input;
7245    },
7246    meridiem: function (hour, minute, isLower) {
7247        if (hour < 12) {
7248            return 'ص';
7249        } else {
7250            return 'م';
7251        }
7252    },
7253    calendar: {
7254        sameDay: '[اليوم عند الساعة] LT',
7255        nextDay: '[غدًا عند الساعة] LT',
7256        nextWeek: 'dddd [عند الساعة] LT',
7257        lastDay: '[أمس عند الساعة] LT',
7258        lastWeek: 'dddd [عند الساعة] LT',
7259        sameElse: 'L',
7260    },
7261    relativeTime: {
7262        future: 'بعد %s',
7263        past: 'منذ %s',
7264        s: pluralize('s'),
7265        ss: pluralize('s'),
7266        m: pluralize('m'),
7267        mm: pluralize('m'),
7268        h: pluralize('h'),
7269        hh: pluralize('h'),
7270        d: pluralize('d'),
7271        dd: pluralize('d'),
7272        M: pluralize('M'),
7273        MM: pluralize('M'),
7274        y: pluralize('y'),
7275        yy: pluralize('y'),
7276    },
7277    postformat: function (string) {
7278        return string.replace(/,/g, '،');
7279    },
7280    week: {
7281        dow: 0, // Sunday is the first day of the week.
7282        doy: 4, // The week that contains Jan 4th is the first week of the year.
7283    },
7284}));
7285
7286
7287/***/ }),
7288/* 13 */
7289/***/ (function(module, __webpack_exports__, __webpack_require__) {
7290
7291"use strict";
7292Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
7293/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
7294//! moment.js locale configuration
7295//! locale : Arabic (Kuwait) [ar-kw]
7296//! author : Nusret Parlak: https://github.com/nusretparlak
7297
7298
7299
7300/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ar-kw', {
7301    months: 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split(
7302        '_'
7303    ),
7304    monthsShort: 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split(
7305        '_'
7306    ),
7307    weekdays: 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
7308    weekdaysShort: 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
7309    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
7310    weekdaysParseExact: true,
7311    longDateFormat: {
7312        LT: 'HH:mm',
7313        LTS: 'HH:mm:ss',
7314        L: 'DD/MM/YYYY',
7315        LL: 'D MMMM YYYY',
7316        LLL: 'D MMMM YYYY HH:mm',
7317        LLLL: 'dddd D MMMM YYYY HH:mm',
7318    },
7319    calendar: {
7320        sameDay: '[اليوم على الساعة] LT',
7321        nextDay: '[غدا على الساعة] LT',
7322        nextWeek: 'dddd [على الساعة] LT',
7323        lastDay: '[أمس على الساعة] LT',
7324        lastWeek: 'dddd [على الساعة] LT',
7325        sameElse: 'L',
7326    },
7327    relativeTime: {
7328        future: 'في %s',
7329        past: 'منذ %s',
7330        s: 'ثوان',
7331        ss: '%d ثانية',
7332        m: 'دقيقة',
7333        mm: '%d دقائق',
7334        h: 'ساعة',
7335        hh: '%d ساعات',
7336        d: 'يوم',
7337        dd: '%d أيام',
7338        M: 'شهر',
7339        MM: '%d أشهر',
7340        y: 'سنة',
7341        yy: '%d سنوات',
7342    },
7343    week: {
7344        dow: 0, // Sunday is the first day of the week.
7345        doy: 12, // The week that contains Jan 12th is the first week of the year.
7346    },
7347}));
7348
7349
7350/***/ }),
7351/* 14 */
7352/***/ (function(module, __webpack_exports__, __webpack_require__) {
7353
7354"use strict";
7355Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
7356/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
7357//! moment.js locale configuration
7358//! locale : Arabic (Lybia) [ar-ly]
7359//! author : Ali Hmer: https://github.com/kikoanis
7360
7361
7362
7363var symbolMap = {
7364        1: '1',
7365        2: '2',
7366        3: '3',
7367        4: '4',
7368        5: '5',
7369        6: '6',
7370        7: '7',
7371        8: '8',
7372        9: '9',
7373        0: '0',
7374    },
7375    pluralForm = function (n) {
7376        return n === 0
7377            ? 0
7378            : n === 1
7379            ? 1
7380            : n === 2
7381            ? 2
7382            : n % 100 >= 3 && n % 100 <= 10
7383            ? 3
7384            : n % 100 >= 11
7385            ? 4
7386            : 5;
7387    },
7388    plurals = {
7389        s: [
7390            'أقل من ثانية',
7391            'ثانية واحدة',
7392            ['ثانيتان', 'ثانيتين'],
7393            '%d ثوان',
7394            '%d ثانية',
7395            '%d ثانية',
7396        ],
7397        m: [
7398            'أقل من دقيقة',
7399            'دقيقة واحدة',
7400            ['دقيقتان', 'دقيقتين'],
7401            '%d دقائق',
7402            '%d دقيقة',
7403            '%d دقيقة',
7404        ],
7405        h: [
7406            'أقل من ساعة',
7407            'ساعة واحدة',
7408            ['ساعتان', 'ساعتين'],
7409            '%d ساعات',
7410            '%d ساعة',
7411            '%d ساعة',
7412        ],
7413        d: [
7414            'أقل من يوم',
7415            'يوم واحد',
7416            ['يومان', 'يومين'],
7417            '%d أيام',
7418            '%d يومًا',
7419            '%d يوم',
7420        ],
7421        M: [
7422            'أقل من شهر',
7423            'شهر واحد',
7424            ['شهران', 'شهرين'],
7425            '%d أشهر',
7426            '%d شهرا',
7427            '%d شهر',
7428        ],
7429        y: [
7430            'أقل من عام',
7431            'عام واحد',
7432            ['عامان', 'عامين'],
7433            '%d أعوام',
7434            '%d عامًا',
7435            '%d عام',
7436        ],
7437    },
7438    pluralize = function (u) {
7439        return function (number, withoutSuffix, string, isFuture) {
7440            var f = pluralForm(number),
7441                str = plurals[u][pluralForm(number)];
7442            if (f === 2) {
7443                str = str[withoutSuffix ? 0 : 1];
7444            }
7445            return str.replace(/%d/i, number);
7446        };
7447    },
7448    months = [
7449        'يناير',
7450        'فبراير',
7451        'مارس',
7452        'أبريل',
7453        'مايو',
7454        'يونيو',
7455        'يوليو',
7456        'أغسطس',
7457        'سبتمبر',
7458        'أكتوبر',
7459        'نوفمبر',
7460        'ديسمبر',
7461    ];
7462
7463/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ar-ly', {
7464    months: months,
7465    monthsShort: months,
7466    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.spl
7466it('_'),
7467    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
7468    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
7469    weekdaysParseExact: true,
7470    longDateFormat: {
7471        LT: 'HH:mm',
7472        LTS: 'HH:mm:ss',
7473        L: 'D/\u200FM/\u200FYYYY',
7474        LL: 'D MMMM YYYY',
7475        LLL: 'D MMMM YYYY HH:mm',
7476        LLLL: 'dddd D MMMM YYYY HH:mm',
7477    },
7478    meridiemParse: /ص|م/,
7479    isPM: function (input) {
7480        return 'م' === input;
7481    },
7482    meridiem: function (hour, minute, isLower) {
7483        if (hour < 12) {
7484            return 'ص';
7485        } else {
7486            return 'م';
7487        }
7488    },
7489    calendar: {
7490        sameDay: '[اليوم عند الساعة] LT',
7491        nextDay: '[غدًا عند الساعة] LT',
7492        nextWeek: 'dddd [عند الساعة] LT',
7493        lastDay: '[أمس عند الساعة] LT',
7494        lastWeek: 'dddd [عند الساعة] LT',
7495        sameElse: 'L',
7496    },
7497    relativeTime: {
7498        future: 'بعد %s',
7499        past: 'منذ %s',
7500        s: pluralize('s'),
7501        ss: pluralize('s'),
7502        m: pluralize('m'),
7503        mm: pluralize('m'),
7504        h: pluralize('h'),
7505        hh: pluralize('h'),
7506        d: pluralize('d'),
7507        dd: pluralize('d'),
7508        M: pluralize('M'),
7509        MM: pluralize('M'),
7510        y: pluralize('y'),
7511        yy: pluralize('y'),
7512    },
7513    preparse: function (string) {
7514        return string.replace(/،/g, ',');
7515    },
7516    postformat: function (string) {
7517        return string
7518            .replace(/\d/g, function (match) {
7519                return symbolMap[match];
7520            })
7521            .replace(/,/g, '،');
7522    },
7523    week: {
7524        dow: 6, // Saturday is the first day of the week.
7525        doy: 12, // The week that contains Jan 12th is the first week of the year.
7526    },
7527}));
7528
7529
7530/***/ }),
7531/* 15 */
7532/***/ (function(module, __webpack_exports__, __webpack_require__) {
7533
7534"use strict";
7535Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
7536/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
7537//! moment.js locale configuration
7538//! locale : Arabic (Morocco) [ar-ma]
7539//! author : ElFadili Yassine : https://github.com/ElFadiliY
7540//! author : Abdel Said : https://github.com/abdelsaid
7541
7542
7543
7544/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ar-ma', {
7545    months: 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split(
7546        '_'
7547    ),
7548    monthsShort: 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split(
7549        '_'
7550    ),
7551    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
7552    weekdaysShort: 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
7553    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
7554    weekdaysParseExact: true,
7555    longDateFormat: {
7556        LT: 'HH:mm',
7557        LTS: 'HH:mm:ss',
7558        L: 'DD/MM/YYYY',
7559        LL: 'D MMMM YYYY',
7560        LLL: 'D MMMM YYYY HH:mm',
7561        LLLL: 'dddd D MMMM YYYY HH:mm',
7562    },
7563    calendar: {
7564        sameDay: '[اليوم على الساعة] LT',
7565        nextDay: '[غدا على الساعة] LT',
7566        nextWeek: 'dddd [على الساعة] LT',
7567        lastDay: '[أمس على الساعة] LT',
7568        lastWeek: 'dddd [على الساعة] LT',
7569        sameElse: 'L',
7570    },
7571    relativeTime: {
7572        future: 'في %s',
7573        past: 'منذ %s',
7574        s: 'ثوان',
7575        ss: '%d ثانية',
7576        m: 'دقيقة',
7577        mm: '%d دقائق',
7578        h: 'ساعة',
7579        hh: '%d ساعات',
7580        d: 'يوم',
7581        dd: '%d أيام',
7582        M: 'شهر',
7583        MM: '%d أشهر',
7584        y: 'سنة',
7585        yy: '%d سنوات',
7586    },
7587    week: {
7588        dow: 1, // Monday is the first day of the week.
7589        doy: 4, // The week that contains Jan 4th is the first week of the year.
7590    },
7591}));
7592
7593
7594/***/ }),
7595/* 16 */
7596/***/ (function(module, __webpack_exports__, __webpack_require__) {
7597
7598"use strict";
7599Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
7600/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
7601//! moment.js locale configuration
7602//! locale : Arabic (Saudi Arabia) [ar-sa]
7603//! author : Suhail Alkowaileet : https://github.com/xsoh
7604
7605
7606
7607var symbolMap = {
7608        1: 'Ù¡',
7609        2: 'Ù¢',
7610        3: 'Ù£',
7611        4: 'Ù¤',
7612        5: 'Ù¥',
7613        6: 'Ù¦',
7614        7: 'Ù§',
7615        8: 'Ù¨',
7616        9: 'Ù©',
7617        0: 'Ù ',
7618    },
7619    numberMap = {
7620        'Ù¡': '1',
7621        'Ù¢': '2',
7622        'Ù£': '3',
7623        'Ù¤': '4',
7624        'Ù¥': '5',
7625        'Ù¦': '6',
7626        'Ù§': '7',
7627        'Ù¨': '8',
7628        'Ù©': '9',
7629        'Ù ': '0',
7630    };
7631
7632/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ar-sa', {
7633    months: 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split(
7634        '_'
7635    ),
7636    monthsShort: 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split(
7637        '_'
7638    ),
7639    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
7640    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
7641    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
7642    weekdaysParseExact: true,
7643    longDateFormat: {
7644        LT: 'HH:mm',
7645        LTS: 'HH:mm:ss',
7646        L: 'DD/MM/YYYY',
7647        LL: 'D MMMM YYYY',
7648        LLL: 'D MMMM YYYY HH:mm',
7649        LLLL: 'dddd D MMMM YYYY HH:mm',
7650    },
7651    meridiemParse: /ص|م/,
7652    isPM: function (input) {
7653        return 'م' === input;
7654    },
7655    meridiem: function (hour, minute, isLower) {
7656        if (hour < 12) {
7657            return 'ص';
7658        } else {
7659            return 'م';
7660        }
7661    },
7662    calendar: {
7663        sameDay: '[اليوم على الساعة] LT',
7664        nextDay: '[غدا على الساعة] LT',
7665        nextWeek: 'dddd [على الساعة] LT',
7666        lastDay: '[أمس على الساعة] LT',
7667        lastWeek: 'dddd [على الساعة] LT',
7668        sameElse: 'L',
7669    },
7670    relativeTime: {
7671        future: 'في %s',
7672        past: 'منذ %s',
7673        s: 'ثوان',
7674        ss: '%d ثانية',
7675        m: 'دقيقة',
7676        mm: '%d دقائق',
7677        h: 'ساعة',
7678        hh: '%d ساعات',
7679        d: 'يوم',
7680        dd: '%d أيام',
7681        M: 'شهر',
7682        MM: '%d أشهر',
7683        y: 'سنة',
7684        yy: '%d سنوات',
7685    },
7686    preparse: function (string) {
7687        return string
7688            .replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
7689                return numberMap[match];
7690            })
7691            .replace(/،/g, ',');
7692    },
7693    postformat: function (string) {
7694        return string
7695            .replace(/\d/g, function (match) {
7696                return symbolMap[match];
7697            })
7698            .replace(/,/g, '،');
7699    },
7700    week: {
7701        dow: 0, // Sunday is the first day of the week.
7702        doy: 6, // The week that contains Jan 6th is the first week of the year.
7703    },
7704}));
7705
7706
7707/***/ }),
7708/* 17 */
7709/***/ (function(module, __webpack_exports__, __webpack_require__) {
7710
7711"use strict";
7712Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
7713/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
7714//! moment.js locale configuration
7715//! locale  :  Arabic (Tunisia) [ar-tn]
7716//! author : Nader Toukabri : https://github.com/naderio
7717
7718
7719
7720/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ar-tn', {
7721    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split(
7722        '_'
7723    ),
7724    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split(
7725        '_'
7726    ),
7727    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
7728    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
7729    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
7730    weekdaysParseExact: true,
7731    longDateFormat: {
7732        LT: 'HH:mm',
7733        LTS: 'HH:mm:ss',
7734        L: 'DD/MM/YYYY',
7735        LL: 'D MMMM YYYY',
7736        LLL: 'D MMMM YYYY HH:mm',
7737        LLLL: 'dddd D MMMM YYYY HH:mm',
7738    },
7739    calendar: {
7740        sameDay: '[اليوم على الساعة] LT',
7741        nextDay: '[غدا على الساعة] LT',
7742        nextWeek: 'dddd [على الساعة] LT',
7743        lastDay: '[أمس على الساعة] LT',
7744        lastWeek: 'dddd [على الساعة] LT',
7745        sameElse: 'L',
7746    },
7747    relativeTime: {
7748        future: 'في %s',
7749        past: 'منذ %s',
7750        s: 'ثوان',
7751        ss: '%d ثانية',
7752        m: 'دقيقة',
7753        mm: '%d دقائق',
7754        h: 'ساعة',
7755        hh: '%d ساعات',
7756        d: 'يوم',
7757        dd: '%d أيام',
7758        M: 'شهر',
7759        MM: '%d أشهر',
7760        y: 'سنة',
7761        yy: '%d سنوات',
7762    },
7763    week: {
7764        dow: 1, // Monday is the first day of the week.
7765        doy: 4, // The week that contains Jan 4th is the first week of the year.
7766    },
7767}));
7768
7769
7770/***/ }),
7771/* 18 */
7772/***/ (function(module, __webpack_exports__, __webpack_require__) {
7773
7774"use strict";
7775Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
7776/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
7777//! moment.js locale configuration
7778//! locale : Azerbaijani [az]
7779//! author : topchiyev : https://github.com/topchiyev
7780
7781
7782
7783var suffixes = {
7784    1: '-inci',
7785    5: '-inci',
7786    8: '-inci',
7787    70: '-inci',
7788    80: '-inci',
7789    2: '-nci',
7790    7: '-nci',
7791    20: '-nci',
7792    50: '-nci',
7793    3: '-üncü',
7794    4: '-üncü',
7795    100: '-üncü',
7796    6: '-ncı',
7797    9: '-uncu',
7798    10: '-uncu',
7799    30: '-uncu',
7800    60: '-ıncı',
7801    90: '-ıncı',
7802};
7803
7804/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('az', {
7805    months: 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split(
7806        '_'
7807    ),
7808    monthsShort: 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),
7809    weekdays: 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split(
7810        '_'
7811    ),
7812    weekdaysShort: 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),
7813    weekdaysMin: 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),
7814    weekdaysParseExact: true,
7815    longDateFormat: {
7816        LT: 'HH:mm',
7817        LTS: 'HH:mm:ss',
7818        L: 'DD.MM.YYYY',
7819        LL: 'D MMMM YYYY',
7820        LLL: 'D MMMM YYYY HH:mm',
7821        LLLL: 'dddd, D MMMM YYYY HH:mm',
7822    },
7823    calendar: {
7824        sameDay: '[bugün saat] LT',
7825        nextDay: '[sabah saat] LT',
7826        nextWeek: '[gələn həftə] dddd [saat] LT',
7827        lastDay: '[dünən] LT',
7828        lastWeek: '[keçən həftə] dddd [saat] LT',
7829        sameElse: 'L',
7830    },
7831    relativeTime: {
7832        future: '%s sonra',
7833        past: '%s əvvəl',
7834        s: 'bir neçə saniyə',
7835        ss: '%d saniyə',
7836        m: 'bir dəqiqə',
7837        mm: '%d dəqiqə',
7838        h: 'bir saat',
7839        hh: '%d saat',
7840        d: 'bir gün',
7841        dd: '%d gün',
7842        M: 'bir ay',
7843        MM: '%d ay',
7844        y: 'bir il',
7845        yy: '%d il',
7846    },
7847    meridiemParse: /gecə|səhər|gündüz|axşam/,
7848    isPM: function (input) {
7849        return /^(gündüz|axşam)$/.test(input);
7850    },
7851    meridiem: function (hour, minute, isLower) {
7852        if (hour < 4) {
7853            return 'gecə';
7854        } else if (hour < 12) {
7855            return 'səhər';
7856        } else if (hour < 17) {
7857            return 'gündüz';
7858        } else {
7859            return 'axşam';
7860        }
7861    },
7862    dayOfMonthOrdinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,
7863    ordinal: function (number) {
7864        if (number === 0) {
7865            // special case for zero
7866            return number + '-ıncı';
7867        }
7868        var a = number % 10,
7869            b = (number % 100) - a,
7870            c = number >= 100 ? 100 : null;
7871        return number + (suffixes[a] || suffixes[b] || suffixes[c]);
7872    },
7873    week: {
7874        dow: 1, // Monday is the first day of the week.
7875        doy: 7, // The week that contains Jan 7th is the first week of the year.
7876    },
7877}));
7878
7879
7880/***/ }),
7881/* 19 */
7882/***/ (function(module, __webpack_exports__, __webpack_require__) {
7883
7884"use strict";
7885Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
7886/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
7887//! moment.js locale configuration
7888//! locale : Belarusian [be]
vendor: 15,056 bytes, lines 7889-8321
7889//! author : Dmitry Demidov : https://github.com/demidov91
7890//! author: Praleska: http://praleska.pro/
7891//! Author : Menelion Elensúle : https://github.com/Oire
7892
7893
7894
7895function plural(word, num) {
7896    var forms = word.split('_');
7897    return num % 10 === 1 && num % 100 !== 11
7898        ? forms[0]
7899        : num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20)
7900        ? forms[1]
7901        : forms[2];
7902}
7903function relativeTimeWithPlural(number, withoutSuffix, key) {
7904    var format = {
7905        ss: withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд',
7906        mm: withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',
7907        hh: withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',
7908        dd: 'дзень_дні_дзён',
7909        MM: 'месяц_месяцы_месяцаў',
7910        yy: 'год_гады_гадоў',
7911    };
7912    if (key === 'm') {
7913        return withoutSuffix ? 'хвіліна' : 'хвіліну';
7914    } else if (key === 'h') {
7915        return withoutSuffix ? 'гадзіна' : 'гадзіну';
7916    } else {
7917        return number + ' ' + plural(format[key], +number);
7918    }
7919}
7920
7921/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('be', {
7922    months: {
7923        format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split(
7924            '_'
7925        ),
7926        standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split(
7927            '_'
7928        ),
7929    },
7930    monthsShort: 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split(
7931        '_'
7932    ),
7933    weekdays: {
7934        format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split(
7935            '_'
7936        ),
7937        standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split(
7938            '_'
7939        ),
7940        isFormat: /\[ ?[Ууў] ?(?:мінулую|наступную)? ?\] ?dddd/,
7941    },
7942    weekdaysShort: 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
7943    weekdaysMin: 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
7944    longDateFormat: {
7945        LT: 'HH:mm',
7946        LTS: 'HH:mm:ss',
7947        L: 'DD.MM.YYYY',
7948        LL: 'D MMMM YYYY г.',
7949        LLL: 'D MMMM YYYY г., HH:mm',
7950        LLLL: 'dddd, D MMMM YYYY г., HH:mm',
7951    },
7952    calendar: {
7953        sameDay: '[Сёння ў] LT',
7954        nextDay: '[Заўтра ў] LT',
7955        lastDay: '[Учора ў] LT',
7956        nextWeek: function () {
7957            return '[У] dddd [ў] LT';
7958        },
7959        lastWeek: function () {
7960            switch (this.day()) {
7961                case 0:
7962                case 3:
7963                case 5:
7964                case 6:
7965                    return '[У мінулую] dddd [ў] LT';
7966                case 1:
7967                case 2:
7968                case 4:
7969                    return '[У мінулы] dddd [ў] LT';
7970            }
7971        },
7972        sameElse: 'L',
7973    },
7974    relativeTime: {
7975        future: 'праз %s',
7976        past: '%s таму',
7977        s: 'некалькі секунд',
7978        m: relativeTimeWithPlural,
7979        mm: relativeTimeWithPlural,
7980        h: relativeTimeWithPlural,
7981        hh: relativeTimeWithPlural,
7982        d: 'дзень',
7983        dd: relativeTimeWithPlural,
7984        M: 'месяц',
7985        MM: relativeTimeWithPlural,
7986        y: 'год',
7987        yy: relativeTimeWithPlural,
7988    },
7989    meridiemParse: /ночы|раніцы|дня|вечара/,
7990    isPM: function (input) {
7991        return /^(дня|вечара)$/.test(input);
7992    },
7993    meridiem: function (hour, minute, isLower) {
7994        if (hour < 4) {
7995            return 'ночы';
7996        } else if (hour < 12) {
7997            return 'раніцы';
7998        } else if (hour < 17) {
7999            return 'дня';
8000        } else {
8001            return 'вечара';
8002        }
8003    },
8004    dayOfMonthOrdinalParse: /\d{1,2}-(і|ы|га)/,
8005    ordinal: function (number, period) {
8006        switch (period) {
8007            case 'M':
8008            case 'd':
8009            case 'DDD':
8010            case 'w':
8011            case 'W':
8012                return (number % 10 === 2 || number % 10 === 3) &&
8013                    number % 100 !== 12 &&
8014                    number % 100 !== 13
8015                    ? number + '-і'
8016                    : number + '-ы';
8017            case 'D':
8018                return number + '-га';
8019            default:
8020                return number;
8021        }
8022    },
8023    week: {
8024        dow: 1, // Monday is the first day of the week.
8025        doy: 7, // The week that contains Jan 7th is the first week of the year.
8026    },
8027}));
8028
8029
8030/***/ }),
8031/* 20 */
8032/***/ (function(module, __webpack_exports__, __webpack_require__) {
8033
8034"use strict";
8035Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
8036/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
8037//! moment.js locale configuration
8038//! locale : Bulgarian [bg]
8039//! author : Krasen Borisov : https://github.com/kraz
8040
8041
8042
8043/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('bg', {
8044    months: 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split(
8045        '_'
8046    ),
8047    monthsShort: 'яну_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),
8048    weekdays: 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split(
8049        '_'
8050    ),
8051    weekdaysShort: 'нед_пон_вто_сря_чет_пет_съб'.split('_'),
8052    weekdaysMin: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
8053    longDateFormat: {
8054        LT: 'H:mm',
8055        LTS: 'H:mm:ss',
8056        L: 'D.MM.YYYY',
8057        LL: 'D MMMM YYYY',
8058        LLL: 'D MMMM YYYY H:mm',
8059        LLLL: 'dddd, D MMMM YYYY H:mm',
8060    },
8061    calendar: {
8062        sameDay: '[Днес в] LT',
8063        nextDay: '[Утре в] LT',
8064        nextWeek: 'dddd [в] LT',
8065        lastDay: '[Вчера в] LT',
8066        lastWeek: function () {
8067            switch (this.day()) {
8068                case 0:
8069                case 3:
8070                case 6:
8071                    return '[Миналата] dddd [в] LT';
8072                case 1:
8073                case 2:
8074                case 4:
8075                case 5:
8076                    return '[Миналия] dddd [в] LT';
8077            }
8078        },
8079        sameElse: 'L',
8080    },
8081    relativeTime: {
8082        future: 'след %s',
8083        past: 'преди %s',
8084        s: 'няколко секунди',
8085        ss: '%d секунди',
8086        m: 'минута',
8087        mm: '%d минути',
8088        h: 'час',
8089        hh: '%d часа',
8090        d: 'ден',
8091        dd: '%d дена',
8092        w: 'седмица',
8093        ww: '%d седмици',
8094        M: 'месец',
8095        MM: '%d месеца',
8096        y: 'година',
8097        yy: '%d години',
8098    },
8099    dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
8100    ordinal: function (number) {
8101        var lastDigit = number % 10,
8102            last2Digits = number % 100;
8103        if (number === 0) {
8104            return number + '-ев';
8105        } else if (last2Digits === 0) {
8106            return number + '-ен';
8107        } else if (last2Digits > 10 && last2Digits < 20) {
8108            return number + '-ти';
8109        } else if (lastDigit === 1) {
8110            return number + '-ви';
8111        } else if (lastDigit === 2) {
8112            return number + '-ри';
8113        } else if (lastDigit === 7 || lastDigit === 8) {
8114            return number + '-ми';
8115        } else {
8116            return number + '-ти';
8117        }
8118    },
8119    week: {
8120        dow: 1, // Monday is the first day of the week.
8121        doy: 7, // The week that contains Jan 7th is the first week of the year.
8122    },
8123}));
8124
8125
8126/***/ }),
8127/* 21 */
8128/***/ (function(module, __webpack_exports__, __webpack_require__) {
8129
8130"use strict";
8131Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
8132/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
8133//! moment.js locale configuration
8134//! locale : Bambara [bm]
8135//! author : Estelle Comment : https://github.com/estellecomment
8136// Language contact person : Abdoufata Kane : https://github.com/abdoufata
8137
8138
8139
8140/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('bm', {
8141    months: 'Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_Mɛkalo_Zuwɛnkalo_Zuluyekalo_Utikalo_Sɛtanburukalo_ɔkutɔburukalo_Nowanburukalo_Desanburukalo'.split(
8142        '_'
8143    ),
8144    monthsShort: 'Zan_Few_Mar_Awi_Mɛ_Zuw_Zul_Uti_Sɛt_ɔku_Now_Des'.split('_'),
8145    weekdays: 'Kari_Ntɛnɛn_Tarata_Araba_Alamisa_Juma_Sibiri'.split('_'),
8146    weekdaysShort: 'Kar_Ntɛ_Tar_Ara_Ala_Jum_Sib'.split('_'),
8147    weekdaysMin: 'Ka_Nt_Ta_Ar_Al_Ju_Si'.split('_'),
8148    longDateFormat: {
8149        LT: 'HH:mm',
8150        LTS: 'HH:mm:ss',
8151        L: 'DD/MM/YYYY',
8152        LL: 'MMMM [tile] D [san] YYYY',
8153        LLL: 'MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm',
8154        LLLL: 'dddd MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm',
8155    },
8156    calendar: {
8157        sameDay: '[Bi lɛrɛ] LT',
8158        nextDay: '[Sini lɛrɛ] LT',
8159        nextWeek: 'dddd [don lɛrɛ] LT',
8160        lastDay: '[Kunu lɛrɛ] LT',
8161        lastWeek: 'dddd [tɛmɛnen lɛrɛ] LT',
8162        sameElse: 'L',
8163    },
8164    relativeTime: {
8165        future: '%s kɔnɔ',
8166        past: 'a bɛ %s bɔ',
8167        s: 'sanga dama dama',
8168        ss: 'sekondi %d',
8169        m: 'miniti kelen',
8170        mm: 'miniti %d',
8171        h: 'lɛrɛ kelen',
8172        hh: 'lɛrɛ %d',
8173        d: 'tile kelen',
8174        dd: 'tile %d',
8175        M: 'kalo kelen',
8176        MM: 'kalo %d',
8177        y: 'san kelen',
8178        yy: 'san %d',
8179    },
8180    week: {
8181        dow: 1, // Monday is the first day of the week.
8182        doy: 4, // The week that contains Jan 4th is the first week of the year.
8183    },
8184}));
8185
8186
8187/***/ }),
8188/* 22 */
8189/***/ (function(module, __webpack_exports__, __webpack_require__) {
8190
8191"use strict";
8192Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
8193/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
8194//! moment.js locale configuration
8195//! locale : Bengali [bn]
8196//! author : Kaushik Gandhi : https://github.com/kaushikgandhi
8197
8198
8199
8200var symbolMap = {
8201        1: 'à§§',
8202        2: '২',
8203        3: 'à§©',
8204        4: '৪',
8205        5: 'à§«',
8206        6: '৬',
8207        7: 'à§­',
8208        8: 'à§®',
8209        9: '৯',
8210        0: '০',
8211    },
8212    numberMap = {
8213        'à§§': '1',
8214        '২': '2',
8215        'à§©': '3',
8216        '৪': '4',
8217        'à§«': '5',
8218        '৬': '6',
8219        'à§­': '7',
8220        'à§®': '8',
8221        '৯': '9',
8222        '০': '0',
8223    };
8224
8225/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('bn', {
8226    months: 'জানুয়ারি_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split(
8227        '_'
8228    ),
8229    monthsShort: 'জানু_ফেব্রু_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্ট_অক্টো_নভে_ডিসে'.split(
8230        '_'
8231    ),
8232    weekdays: 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split(
8233        '_'
8234    ),
8235    weekdaysShort: 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),
8236    weekdaysMin: 'রবি_সোম_মঙ্গল_বুধ_বৃহ_শুক্র_শনি'.split('_'),
8237    longDateFormat: {
8238        LT: 'A h:mm সময়',
8239        LTS: 'A h:mm:ss সময়',
8240        L: 'DD/MM/YYYY',
8241        LL: 'D MMMM YYYY',
8242        LLL: 'D MMMM YYYY, A h:mm সময়',
8243        LLLL: 'dddd, D MMMM YYYY, A h:mm সময়',
8244    },
8245    calendar: {
8246        sameDay: '[আজ] LT',
8247        nextDay: '[আগামীকাল] LT',
8248        nextWeek: 'dddd, LT',
8249        lastDay: '[গতকাল] LT',
8250        lastWeek: '[গত] dddd, LT',
8251        sameElse: 'L',
8252    },
8253    relativeTime: {
8254        future: '%s পরে',
8255        past: '%s আগে',
8256        s: 'কয়েক সেকেন্ড',
8257        ss: '%d সেকেন্ড',
8258        m: 'এক মিনিট',
8259        mm: '%d মিনিট',
8260        h: 'এক ঘন্টা',
8261        hh: '%d ঘন্টা',
8262        d: 'এক দিন',
8263        dd: '%d দিন',
8264        M: 'এক মাস',
8265        MM: '%d মাস',
8266        y: 'এক বছর',
8267        yy: '%d বছর',
8268    },
8269    preparse: function (string) {
8270        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {
8271            return numberMap[match];
8272        });
8273    },
8274    postformat: function (string) {
8275        return string.replace(/\d/g, function (match) {
8276            return symbolMap[match];
8277        });
8278    },
8279    meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,
8280    meridiemHour: function (hour, meridiem) {
8281        if (hour === 12) {
8282            hour = 0;
8283        }
8284        if (
8285            (meridiem === 'রাত' && hour >= 4) ||
8286            (meridiem === 'দুপুর' && hour < 5) ||
8287            meridiem === 'বিকাল'
8288        ) {
8289            return hour + 12;
8290        } else {
8291            return hour;
8292        }
8293    },
8294    meridiem: function (hour, minute, isLower) {
8295        if (hour < 4) {
8296            return 'রাত';
8297        } else if (hour < 10) {
8298            return 'সকাল';
8299        } else if (hour < 17) {
8300            return 'দুপুর';
8301        } else if (hour < 20) {
8302            return 'বিকাল';
8303        } else {
8304            return 'রাত';
8305        }
8306    },
8307    week: {
8308        dow: 0, // Sunday is the first day of the week.
8309        doy: 6, // The week that contains Jan 6th is the first week of the year.
8310    },
8311}));
8312
8313
8314/***/ }),
8315/* 23 */
8316/***/ (function(module, __webpack_exports__, __webpack_require__) {
8317
8318"use strict";
8319Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
8320/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
8321//! moment.js locale configuration
8322//! locale : Bengali (Bangladesh) [bn-bd]
8323//! author : Asraf Hossain Patoary : https://github.com/ashwoolford
8324
8325
8326
8327var symbolMap = {
8328        1: 'à§§',
8329        2: '২',
8330        3: 'à§©',
8331        4: '৪',
8332        5: 'à§«',
8333        6: '৬',
8334        7: 'à§­',
8335        8: 'à§®',
8336        9: '৯',
8337        0: '০',
8338    },
8339    numberMap = {
8340        'à§§': '1',
8341        '২': '2',
8342        'à§©': '3',
8343        '৪': '4',
8344        'à§«': '5',
8345        '৬': '6',
8346        'à§­': '7',
8347        'à§®': '8',
8348        '৯': '9',
8349        '০': '0',
8350    };
8351
8352/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('bn-bd', {
8353    months: 'জানুয়ারি_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split(
8354        '_'
8355    ),
8356    monthsShort: 'জানু_ফেব্রু_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্ট_অক্টো_নভে_ডিসে'.split(
8357        '_'
8358    ),
8359    weekdays: 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split(
8360        '_'
8361    ),
8362    weekdaysShort: 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),
8363    weekdaysMin: 'রবি_সোম_মঙ্গল_বুধ_বৃহ_শুক্র_শনি'.split('_'),
8364    longDateFormat: {
8365        LT: 'A h:mm সময়',
8366        LTS: 'A h:mm:ss সময়',
8367        L: 'DD/MM/YYYY',
8368        LL: 'D MMMM YYYY',
8369        LLL: 'D MMMM YYYY, A h:mm সময়',
8370        LLLL: 'dddd, D MMMM YYYY, A h:mm সময়',
8371    },
8372    calendar: {
8373        sameDay: '[আজ] LT',
8374        nextDay: '[আগামীকাল] LT',
8375        nextWeek: 'dddd, LT',
8376        lastDay: '[গতকাল] LT',
8377        lastWeek: '[গত] dddd, LT',
8378        sameElse: 'L',
8379    },
8380    relativeTime: {
8381        future: '%s পরে',
8382        past: '%s আগে',
8383        s: 'কয়েক সেকেন্ড',
8384        ss: '%d সেকেন্ড',
8385        m: 'এক মিনিট',
8386        mm: '%d মিনিট',
8387        h: 'এক ঘন্টা',
8388        hh: '%d ঘন্টা',
8389        d: 'এক দিন',
8390        dd: '%d দিন',
8391        M: 'এক মাস',
8392        MM: '%d মাস',
8393        y: 'এক বছর',
8394        yy: '%d বছর',
8395    },
8396    preparse: function (string) {
8397        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {
8398            return numberMap[match];
8399        });
8400    },
8401    postformat: function (string) {
8402        return string.replace(/\d/g, function (match) {
8403            return symbolMap[match];
8404        });
8405    },
8406
8407    meridiemParse: /রাত|ভোর|সকাল|দুপুর|বিকাল|সন্ধ্যা|রাত/,
8408    meridiemHour: function (hour, meridiem) {
8409        if (hour === 12) {
8410            hour = 0;
8411        }
8412        if (meridiem === 'রাত') {
8413            return hour < 4 ? hour : hour + 12;
8414        } else if (meridiem === 'ভোর') {
8415            return hour;
8416        } else if (meridiem === 'সকাল') {
8417            return hour;
8418        } else if (meridiem === 'দুপুর') {
8419            return hour >= 3 ? hour : hour + 12;
8420        } else if (meridiem === 'বিকাল') {
8421            return hour + 12;
8422        } else if (meridiem === 'সন্ধ্যা') {
8423            return hour + 12;
8424        }
8425    },
8426
8427    meridiem: function (hour, minute, isLower) {
8428        if (hour < 4) {
8429            return 'রাত';
8430        } else if (hour < 6) {
8431            return 'ভোর';
8432        } else if (hour < 12) {
8433            return 'সকাল';
8434        } else if (hour < 15) {
8435            return 'দুপুর';
8436        } else if (hour < 18) {
8437            return 'বিকাল';
8438        } else if (hour < 20) {
8439            return 'সন্ধ্যা';
8440        } else {
8441            return 'রাত';
8442        }
8443    },
8444    week: {
8445        dow: 0, // Sunday is the first day of the week.
8446        doy: 6, // The week that contains Jan 6th is the first week of the year.
8447    },
8448}));
8449
8450
8451/***/ }),
8452/* 24 */
8453/***/ (function(module, __webpack_exports__, __webpack_require__) {
8454
8455"use strict";
8456Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
8457/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
8458//! moment.js locale configuration
8459//! locale : Tibetan [bo]
8460//! author : Thupten N. Chakrishar : https://github.com/vajradog
8461
8462
8463
8464var symbolMap = {
8465        1: '༡',
8466        2: '༢',
8467        3: '༣',
8468        4: '༤',
8469        5: '༥',
8470        6: '༦',
8471        7: '༧',
8472        8: '༨',
8473        9: '༩',
8474        0: '༠',
8475    },
8476    numberMap = {
8477        '༡': '1',
8478        '༢': '2',
8479        '༣': '3',
8480        '༤': '4',
8481        '༥': '5',
8482        '༦': '6',
8483        '༧': '7',
8484        '༨': '8',
8485        '༩': '9',
8486        '༠': '0',
8487    };
8488
8489/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('bo', {
8490    months: 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split(
8491        '_'
8492    ),
8493    monthsShort: 'ཟླ་1_ཟླ་2_ཟླ་3_ཟླ་4_ཟླ་5_ཟླ་6_ཟླ་7_ཟླ་8_ཟླ་9_ཟླ་10_ཟླ་11_ཟླ་12'.split(
8494        '_'
8495    ),
8496    monthsShortRegex: /^(ཟླ་\d{1,2})/,
8497    monthsParseExact: true,
8498    weekdays: 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split(
8499        '_'
8500    ),
8501    weekdaysShort: 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split(
8502        '_'
8503    ),
8504    weekdaysMin: 'ཉི_ཟླ_མིག_ལྷག_ཕུར_སངས_སྤེན'.split('_'),
8505    longDateFormat: {
8506        LT: 'A h:mm',
8507        LTS: 'A h:mm:ss',
8508        L: 'DD/MM/YYYY',
8509        LL: 'D MMMM YYYY',
8510        LLL: 'D MMMM YYYY, A h:mm',
8511        LLLL: 'dddd, D MMMM YYYY, A h:mm',
8512    },
8513    calendar: {
8514        sameDay: '[དི་རིང] LT',
8515        nextDay: '[སང་ཉིན] LT',
8516        nextWeek: '[བདུན་ཕྲག་རྗེས་མ], LT',
8517        lastDay: '[ཁ་སང] LT',
8518        lastWeek: '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',
8519        sameElse: 'L',
8520    },
8521    relativeTime: {
8522        future: '%s ལ་',
8523        past: '%s སྔན་ལ',
8524        s: 'ལམ་སང',
8525        ss: '%d སྐར་ཆ།',
8526        m: 'སྐར་མ་གཅིག',
8527        mm: '%d སྐར་མ',
8528        h: 'ཆུ་ཚོད་གཅིག',
8529        hh: '%d ཆུ་ཚོད',
8530        d: 'ཉིན་གཅིག',
8531        dd: '%d ཉིན་',
8532        M: 'ཟླ་བ་གཅིག',
8533        MM: '%d ཟླ་བ',
8534        y: 'ལོ་གཅིག',
8535        yy: '%d ལོ',
8536    },
8537    preparse: function (string) {
8538        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {
8539            return numberMap[match];
8540        });
8541    },
8542    postformat: function (string) {
8543        return string.replace(/\d/g, function (match) {
8544            return symbolMap[match];
8545        });
8546    },
8547    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,
8548    meridiemHour: function (hour, meridiem) {
8549        if (hour === 12) {
8550            hour = 0;
8551        }
8552        if (
8553            (meridiem === 'མཚན་མོ' && hour >= 4) ||
8554            (meridiem === 'ཉིན་གུང' && hour < 5) ||
8555            meridiem === 'དགོང་དག'
8556        ) {
8557            return hour + 12;
8558        } else {
8559            return hour;
8560        }
8561    },
8562    meridiem: function (hour, minute, isLower) {
8563        if (hour < 4) {
8564            return 'མཚན་མོ';
8565        } else if (hour < 10) {
8566            return 'ཞོགས་ཀས';
8567        } else if (hour < 17) {
8568            return 'ཉིན་གུང';
8569        } else if (hour < 20) {
8570            return 'དགོང་དག';
8571        } else {
8572            return 'མཚན་མོ';
8573        }
8574    },
8575    week: {
8576        dow: 0, // Sunday is the first day of the week.
8577        doy: 6, // The week that contains Jan 6th is the first week of the year.
8578    },
8579}));
8580
8581
8582/***/ }),
8583/* 25 */
8584/***/ (function(module, __webpack_exports__, __webpack_require__) {
8585
8586"use strict";
8587Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
8588/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
8589//! moment.js locale configuration
8590//! locale : Breton [br]
8591//! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
8592
8593
8594
8595function relativeTimeWithMutation(number, withoutSuffix, key) {
8596    var format = {
8597        mm: 'munutenn',
8598        MM: 'miz',
8599        dd: 'devezh',
8600    };
8601    return number + ' ' + mutation(format[key], number);
8602}
8603function specialMutationForYears(number) {
8604    switch (lastNumber(number)) {
8605        case 1:
8606        case 3:
8607        case 4:
8608        case 5:
8609        case 9:
8610            return number + ' bloaz';
8611        default:
8612            return number + ' vloaz';
8613    }
8614}
8615function lastNumber(number) {
8616    if (number > 9) {
8617        return lastNumber(number % 10);
8618    }
8619    return number;
8620}
8621function mutation(text, number) {
8622    if (number === 2) {
8623        return softMutation(text);
8624    }
8625    return text;
8626}
8627function softMutation(text) {
8628    var mutationTable = {
8629        m: 'v',
8630        b: 'v',
8631        d: 'z',
8632    };
8633    if (mutationTable[text.charAt(0)] === undefined) {
8634        return text;
8635    }
8636    return mutationTable[text.charAt(0)] + text.substring(1);
8637}
8638
8639var monthsParse = [
8640        /^gen/i,
8641        /^c[ʼ\']hwe/i,
8642        /^meu/i,
8643        /^ebr/i,
8644        /^mae/i,
8645        /^(mez|eve)/i,
8646        /^gou/i,
8647        /^eos/i,
8648        /^gwe/i,
8649        /^her/i,
8650        /^du/i,
8651        /^ker/i,
8652    ],
8653    monthsRegex = /^(genver|c[ʼ\']hwevrer|meurzh|ebrel|mae|mezheven|gouere|eost|gwengolo|here|du|kerzu|gen|c[ʼ\']hwe|meu|ebr|mae|eve|gou|eos|gwe|her|du|ker)/i,
8654    monthsStrictRegex = /^(genver|c[ʼ\']hwevrer|meurzh|ebrel|mae|mezheven|gouere|eost|gwengolo|here|du|kerzu)/i,
8655    monthsShortStrictRegex = /^(gen|c[ʼ\']hwe|meu|ebr|mae|eve|gou|eos|gwe|her|du|ker)/i,
8656    fullWeekdaysParse = [
8657        /^sul/i,
8658        /^lun/i,
8659        /^meurzh/i,
8660        /^merc[ʼ\']her/i,
8661        /^yaou/i,
8662        /^gwener/i,
8663        /^sadorn/i,
8664    ],
8665    shortWeekdaysParse = [
8666        /^Sul/i,
8667        /^Lun/i,
8668        /^Meu/i,
8669        /^Mer/i,
8670        /^Yao/i,
8671        /^Gwe/i,
8672        /^Sad/i,
8673    ],
8674    minWeekdaysParse = [
8675        /^Su/i,
8676        /^Lu/i,
8677        /^Me([^r]|$)/i,
8678        /^Mer/i,
8679        /^Ya/i,
8680        /^Gw/i,
8681        /^Sa/i,
8682    ];
8683
8684/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('br', {
8685    months: 'Genver_Cʼhwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split(
8686        '_'
8687    ),
8688    monthsShort: 'Gen_Cʼhwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),
8689    weekdays: 'Sul_Lun_Meurzh_Mercʼher_Yaou_Gwener_Sadorn'.split('_'),
8690    weekdaysShort: 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),
8691    weekdaysMin: 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),
8692    weekdaysParse: minWeekdaysParse,
8693    fullWeekdaysParse: fullWeekdaysParse,
8694    shortWeekdaysParse: shortWeekdaysParse,
8695    minWeekdaysParse: minWeekdaysParse,
8696
8697    monthsRegex: monthsRegex,
8698    monthsShortRegex: monthsRegex,
8699    monthsStrictRegex: monthsStrictRegex,
8700    monthsShortStrictRegex: monthsShortStrictRegex,
8701    monthsParse: monthsParse,
8702    longMonthsParse: monthsParse,
8703    shortMonthsParse: monthsParse,
8704
8705    longDateFormat: {
8706        LT: 'HH:mm',
8707        LTS: 'HH:mm:ss',
8708        L: 'DD/MM/YYYY',
8709        LL: 'D [a viz] MMMM YYYY',
8710        LLL: 'D [a viz] MMMM YYYY HH:mm',
8711        LLLL: 'dddd, D [a viz] MMMM YYYY HH:mm',
8712    },
8713    calendar: {
8714        sameDay: '[Hiziv da] LT',
8715        nextDay: '[Warcʼhoazh da] LT',
8716        nextWeek: 'dddd [da] LT',
8717        lastDay: '[Decʼh da] LT',
8718        lastWeek: 'dddd [paset da] LT',
8719        sameElse: 'L',
8720    },
8721    relativeTime: {
8722        future: 'a-benn %s',
8723        past: '%s ʼzo',
8724        s: 'un nebeud segondennoù',
8725        ss: '%d eilenn',
8726        m: 'ur vunutenn',
8727        mm: relativeTimeWithMutation,
8728        h: 'un eur',
8729        hh: '%d eur',
8730        d: 'un devezh',
8731        dd: relativeTimeWithMutation,
8732        M: 'ur miz',
8733        MM: relativeTimeWithMutation,
8734        y: 'ur bloaz',
8735        yy: specialMutationForYears,
8736    },
8737    dayOfMonthOrdinalParse: /\d{1,2}(añ|vet)/,
8738    ordinal: function (number) {
8739        var output = number === 1 ? 'añ' : 'vet';
8740        return number + output;
8741    },
8742    week: {
8743        dow: 1, // Monday is the first day of the week.
8744        doy: 4, // The week that contains Jan 4th is the first week of the year.
8745    },
8746    meridiemParse: /a.m.|g.m./, // goude merenn | a-raok merenn
8747    isPM: function (token) {
8748        return token === 'g.m.';
8749    },
8750    meridiem: function (hour, minute, isLower) {
8751        return hour < 12 ? 'a.m.' : 'g.m.';
8752    },
8753}));
8754
8755
8756/***/ }),
8757/* 26 */
8758/***/ (function(module, __webpack_exports__, __webpack_require__) {
8759
8760"use strict";
8761Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
8762/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
8763//! moment.js locale configuration
8764//! locale : Bosnian [bs]
8765//! author : Nedim Cholich : https://github.com/frontyard
8766//! based on (hr) translation by Bojan Marković
8767
8768
8769
8770function translate(number, withoutSuffix, key) {
8771    var result = number + ' ';
8772    switch (key) {
8773        case 'ss':
8774            if (number === 1) {
8775                result += 'sekunda';
8776            } else if (number === 2 || number === 3 || number === 4) {
8777                result += 'sekunde';
8778            } else {
8779                result += 'sekundi';
8780            }
8781            return result;
8782        case 'm':
8783            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
8784        case 'mm':
8785            if (number === 1) {
8786                result += 'minuta';
8787            } else if (number === 2 || number === 3 || number === 4) {
8788                result += 'minute';
8789            } else {
8790                result += 'minuta';
8791            }
8792            return result;
8793        case 'h':
8794            return withoutSuffix ? 'jedan sat' : 'jednog sata';
8795        case 'hh':
8796            if (number === 1) {
8797                result += 'sat';
8798            } else if (number === 2 || number === 3 || number === 4) {
8799                result += 'sata';
8800            } else {
8801                result += 'sati';
8802            }
8803            return result;
8804        case 'dd':
8805            if (number === 1) {
8806                result += 'dan';
8807            } else {
8808                result += 'dana';
8809            }
8810            return result;
8811        case 'MM':
8812            if (number === 1) {
8813                result += 'mjesec';
8814            } else if (number === 2 || number === 3 || number === 4) {
8815                result += 'mjeseca';
8816            } else {
8817                result += 'mjeseci';
8818            }
8819            return result;
8820        case 'yy':
8821            if (number === 1) {
8822                result += 'godina';
8823            } else if (number === 2 || number === 3 || number === 4) {
8824                result += 'godine';
8825            } else {
8826                result += 'godina';
8827            }
8828            return result;
8829    }
8830}
8831
8832/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('bs', {
8833    months: 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split(
8834        '_'
8835    ),
8836    monthsShort: 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split(
8837        '_'
8838    ),
8839    monthsParseExact: true,
8840    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split(
8841        '_'
8842    ),
8843    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
8844    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),
8845    weekdaysParseExact: true,
8846    longDateFormat: {
8847        LT: 'H:mm',
8848        LTS: 'H:mm:ss',
8849        L: 'DD.MM.YYYY',
8850        LL: 'D. MMMM YYYY',
8851        LLL: 'D. MMMM YYYY H:mm',
8852        LLLL: 'dddd, D. MMMM YYYY H:mm',
8853    },
8854    calendar: {
8855        sameDay: '[danas u] LT',
8856        nextDay: '[sutra u] LT',
8857        nextWeek: function () {
8858            switch (this.day()) {
8859                case 0:
8860                    return '[u] [nedjelju] [u] LT';
8861                case 3:
8862                    return '[u] [srijedu] [u] LT';
8863                case 6:
8864                    return '[u] [subotu] [u] LT';
8865                case 1:
8866                case 2:
8867                case 4:
8868                case 5:
8869                    return '[u] dddd [u] LT';
8870            }
8871        },
8872        lastDay: '[jučer u] LT',
8873        lastWeek: function () {
8874            switch (this.day()) {
8875                case 0:
8876                case 3:
8877                    return '[prošlu] dddd [u] LT';
8878                case 6:
8879                    return '[prošle] [subote] [u] LT';
8880                case 1:
8881                case 2:
8882                case 4:
8883                case 5:
8884                    return '[prošli] dddd [u] LT';
8885            }
8886        },
8887        sameElse: 'L',
8888    },
8889    relativeTime: {
8890        future: 'za %s',
8891        past: 'prije %s',
8892        s: 'par sekundi',
8893        ss: translate,
8894        m: translate,
8895        mm: translate,
8896        h: translate,
8897        hh: translate,
8898        d: 'dan',
8899        dd: translate,
8900        M: 'mjesec',
8901        MM: translate,
8902        y: 'godinu',
8903        yy: translate,
8904    },
8905    dayOfMonthOrdinalParse: /\d{1,2}\./,
8906    ordinal: '%d.',
8907    week: {
8908        dow: 1, // Monday is the first day of the week.
8909        doy: 7, // The week that contains Jan 7th is the first week of the year.
8910    },
8911}));
8912
8913
8914/***/ }),
8915/* 27 */
8916/***/ (function(module, __webpack_exports__, __webpack_require__) {
8917
8918"use strict";
8919Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
8920/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
8921//! moment.js locale configuration
8922//! locale : Catalan [ca]
8923//! author : Juan G. Hurtado : https://github.com/juanghurtado
8924
8925
8926
8927/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ca', {
8928    months: {
8929        standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split(
8930            '_'
8931        ),
8932        format: "de gener_de febrer_de març_d'abril_de maig_de juny_de juliol_d'agost_de setembre_d'octubre_de novembre_de desembre".split(
8933            '_'
8934        ),
8935        isFormat: /D[oD]?(\s)+MMMM/,
8936    },
8937    monthsShort: 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split(
8938        '_'
8939    ),
8940    monthsParseExact: true,
8941    weekdays: 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split(
8942        '_'
8943    ),
8944    weekdaysShort: 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),
8945    weekdaysMin: 'dg_dl_dt_dc_dj_dv_ds'.split('_'),
8946    weekdaysParseExact: true,
8947    longDateFormat: {
8948        LT: 'H:mm',
8949        LTS: 'H:mm:ss',
8950        L: 'DD/MM/YYYY',
8951        LL: 'D MMMM [de] YYYY',
8952        ll: 'D MMM YYYY',
8953        LLL: 'D MMMM [de] YYYY [a les] H:mm',
8954        lll: 'D MMM YYYY, H:mm',
8955        LLLL: 'dddd D MMMM [de] YYYY [a les] H:mm',
8956        llll: 'ddd D MMM YYYY, H:mm',
8957    },
8958    calendar: {
8959        sameDay: function () {
8960            return '[avui a ' + (this.hours() !== 1 ? 'les' : 'la') + '] LT';
8961        },
8962        nextDay: function () {
8963            return '[demà a ' + (this.hours() !== 1 ? 'les' : 'la') + '] LT';
8964        },
8965        nextWeek: function () {
8966            return 'dddd [a ' + (this.hours() !== 1 ? 'les' : 'la') + '] LT';
8967        },
8968        lastDay: function () {
8969            return '[ahir a ' + (this.hours() !== 1 ? 'les' : 'la') + '] LT';
8970        },
8971        lastWeek: function () {
8972            return (
8973                '[el] dddd [passat a ' +
8974                (this.hours() !== 1 ? 'les' : 'la') +
8975                '] LT'
8976            );
8977        },
8978        sameElse: 'L',
8979    },
8980    relativeTime: {
8981        future: "d'aquí %s",
8982        past: 'fa %s',
8983        s: 'uns segons',
8984        ss: '%d segons',
8985        m: 'un minut',
8986        mm: '%d minuts',
8987        h: 'una hora',
8988        hh: '%d hores',
8989        d: 'un dia',
8990        dd: '%d dies',
8991        M: 'un mes',
8992        MM: '%d mesos',
8993        y: 'un any',
8994        yy: '%d anys',
8995    },
8996    dayOfMonthOrdinalParse: /\d{1,2}(r|n|t|è|a)/,
8997    ordinal: function (number, period) {
8998        var output =
8999            number === 1
9000                ? 'r'
9001                : number === 2
9002                ? 'n'
9003                : number === 3
9004                ? 'r'
9005                : number === 4
9006                ? 't'
9007                : 'è';
9008        if (period === 'w' || period === 'W') {
9009            output = 'a';
9010        }
9011        return number + output;
9012    },
9013    week: {
9014        dow: 1, // Monday is the first day of the week.
9015        doy: 4, // The week that contains Jan 4th is the first week of the year.
9016    },
9017}));
9018
9019
9020/***/ }),
9021/* 28 */
9022/***/ (function(module, __webpack_exports__, __webpack_require__) {
9023
9024"use strict";
9025Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
9026/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
9027//! moment.js locale configuration
9028//! locale : Czech [cs]
9029//! author : petrbela : https://github.com/petrbela
9030
9031
9032
9033var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.
vendor: 8,145 bytes, lines 9033-9240
9033split(
9034        '_'
9035    ),
9036    monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_'),
9037    monthsParse = [
9038        /^led/i,
9039        /^úno/i,
9040        /^bře/i,
9041        /^dub/i,
9042        /^kvě/i,
9043        /^(čvn|červen$|června)/i,
9044        /^(čvc|červenec|července)/i,
9045        /^srp/i,
9046        /^zář/i,
9047        /^říj/i,
9048        /^lis/i,
9049        /^pro/i,
9050    ],
9051    // NOTE: 'červen' is substring of 'červenec'; therefore 'červenec' must precede 'červen' in the regex to be fully matched.
9052    // Otherwise parser matches '1. červenec' as '1. červen' + 'ec'.
9053    monthsRegex = /^(leden|únor|březen|duben|květen|červenec|července|červen|června|srpen|září|říjen|listopad|prosinec|led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i;
9054
9055function plural(n) {
9056    return n > 1 && n < 5 && ~~(n / 10) !== 1;
9057}
9058function translate(number, withoutSuffix, key, isFuture) {
9059    var result = number + ' ';
9060    switch (key) {
9061        case 's': // a few seconds / in a few seconds / a few seconds ago
9062            return withoutSuffix || isFuture ? 'pár sekund' : 'pár sekundami';
9063        case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago
9064            if (withoutSuffix || isFuture) {
9065                return result + (plural(number) ? 'sekundy' : 'sekund');
9066            } else {
9067                return result + 'sekundami';
9068            }
9069        case 'm': // a minute / in a minute / a minute ago
9070            return withoutSuffix ? 'minuta' : isFuture ? 'minutu' : 'minutou';
9071        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
9072            if (withoutSuffix || isFuture) {
9073                return result + (plural(number) ? 'minuty' : 'minut');
9074            } else {
9075                return result + 'minutami';
9076            }
9077        case 'h': // an hour / in an hour / an hour ago
9078            return withoutSuffix ? 'hodina' : isFuture ? 'hodinu' : 'hodinou';
9079        case 'hh': // 9 hours / in 9 hours / 9 hours ago
9080            if (withoutSuffix || isFuture) {
9081                return result + (plural(number) ? 'hodiny' : 'hodin');
9082            } else {
9083                return result + 'hodinami';
9084            }
9085        case 'd': // a day / in a day / a day ago
9086            return withoutSuffix || isFuture ? 'den' : 'dnem';
9087        case 'dd': // 9 days / in 9 days / 9 days ago
9088            if (withoutSuffix || isFuture) {
9089                return result + (plural(number) ? 'dny' : 'dní');
9090            } else {
9091                return result + 'dny';
9092            }
9093        case 'M': // a month / in a month / a month ago
9094            return withoutSuffix || isFuture ? 'měsíc' : 'měsícem';
9095        case 'MM': // 9 months / in 9 months / 9 months ago
9096            if (withoutSuffix || isFuture) {
9097                return result + (plural(number) ? 'měsíce' : 'měsíců');
9098            } else {
9099                return result + 'měsíci';
9100            }
9101        case 'y': // a year / in a year / a year ago
9102            return withoutSuffix || isFuture ? 'rok' : 'rokem';
9103        case 'yy': // 9 years / in 9 years / 9 years ago
9104            if (withoutSuffix || isFuture) {
9105                return result + (plural(number) ? 'roky' : 'let');
9106            } else {
9107                return result + 'lety';
9108            }
9109    }
9110}
9111
9112/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('cs', {
9113    months: months,
9114    monthsShort: monthsShort,
9115    monthsRegex: monthsRegex,
9116    monthsShortRegex: monthsRegex,
9117    // NOTE: 'červen' is substring of 'červenec'; therefore 'červenec' must precede 'červen' in the regex to be fully matched.
9118    // Otherwise parser matches '1. červenec' as '1. červen' + 'ec'.
9119    monthsStrictRegex: /^(leden|ledna|února|únor|březen|března|duben|dubna|květen|května|červenec|července|červen|června|srpen|srpna|září|říjen|října|listopadu|listopad|prosinec|prosince)/i,
9120    monthsShortStrictRegex: /^(led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i,
9121    monthsParse: monthsParse,
9122    longMonthsParse: monthsParse,
9123    shortMonthsParse: monthsParse,
9124    weekdays: 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),
9125    weekdaysShort: 'ne_po_út_st_čt_pá_so'.split('_'),
9126    weekdaysMin: 'ne_po_út_st_čt_pá_so'.split('_'),
9127    longDateFormat: {
9128        LT: 'H:mm',
9129        LTS: 'H:mm:ss',
9130        L: 'DD.MM.YYYY',
9131        LL: 'D. MMMM YYYY',
9132        LLL: 'D. MMMM YYYY H:mm',
9133        LLLL: 'dddd D. MMMM YYYY H:mm',
9134        l: 'D. M. YYYY',
9135    },
9136    calendar: {
9137        sameDay: '[dnes v] LT',
9138        nextDay: '[zítra v] LT',
9139        nextWeek: function () {
9140            switch (this.day()) {
9141                case 0:
9142                    return '[v neděli v] LT';
9143                case 1:
9144                case 2:
9145                    return '[v] dddd [v] LT';
9146                case 3:
9147                    return '[ve středu v] LT';
9148                case 4:
9149                    return '[ve čtvrtek v] LT';
9150                case 5:
9151                    return '[v pátek v] LT';
9152                case 6:
9153                    return '[v sobotu v] LT';
9154            }
9155        },
9156        lastDay: '[včera v] LT',
9157        lastWeek: function () {
9158            switch (this.day()) {
9159                case 0:
9160                    return '[minulou neděli v] LT';
9161                case 1:
9162                case 2:
9163                    return '[minulé] dddd [v] LT';
9164                case 3:
9165                    return '[minulou středu v] LT';
9166                case 4:
9167                case 5:
9168                    return '[minulý] dddd [v] LT';
9169                case 6:
9170                    return '[minulou sobotu v] LT';
9171            }
9172        },
9173        sameElse: 'L',
9174    },
9175    relativeTime: {
9176        future: 'za %s',
9177        past: 'před %s',
9178        s: translate,
9179        ss: translate,
9180        m: translate,
9181        mm: translate,
9182        h: translate,
9183        hh: translate,
9184        d: translate,
9185        dd: translate,
9186        M: translate,
9187        MM: translate,
9188        y: translate,
9189        yy: translate,
9190    },
9191    dayOfMonthOrdinalParse: /\d{1,2}\./,
9192    ordinal: '%d.',
9193    week: {
9194        dow: 1, // Monday is the first day of the week.
9195        doy: 4, // The week that contains Jan 4th is the first week of the year.
9196    },
9197}));
9198
9199
9200/***/ }),
9201/* 29 */
9202/***/ (function(module, __webpack_exports__, __webpack_require__) {
9203
9204"use strict";
9205Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
9206/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
9207//! moment.js locale configuration
9208//! locale : Chuvash [cv]
9209//! author : Anatoly Mironov : https://github.com/mirontoli
9210
9211
9212
9213/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('cv', {
9214    months: 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split(
9215        '_'
9216    ),
9217    monthsShort: 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),
9218    weekdays: 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split(
9219        '_'
9220    ),
9221    weekdaysShort: 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),
9222    weekdaysMin: 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),
9223    longDateFormat: {
9224        LT: 'HH:mm',
9225        LTS: 'HH:mm:ss',
9226        L: 'DD-MM-YYYY',
9227        LL: 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',
9228        LLL: 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
9229        LLLL: 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
9230    },
9231    calendar: {
9232        sameDay: '[Паян] LT [сехетре]',
9233        nextDay: '[Ыран] LT [сехетре]',
9234        lastDay: '[Ӗнер] LT [сехетре]',
9235        nextWeek: '[Ҫитес] dddd LT [сехетре]',
9236        lastWeek: '[Иртнӗ] dddd LT [сехетре]',
9237        sameElse: 'L',
9238    },
9239    relativeTime: {
9240        future: function (output) {
9241            var affix = /сехет$/i.exec(output)
9242                ? 'рен'
9243                : /ҫул$/i.exec(output)
9244                ? 'тан'
9245                : 'ран';
9246            return output + affix;
9247        },
9248        past: '%s каялла',
9249        s: 'пӗр-ик ҫеккунт',
9250        ss: '%d ҫеккунт',
9251        m: 'пӗр минут',
9252        mm: '%d минут',
9253        h: 'пӗр сехет',
9254        hh: '%d сехет',
9255        d: 'пӗр кун',
9256        dd: '%d кун',
9257        M: 'пӗр уйӑх',
9258        MM: '%d уйӑх',
9259        y: 'пӗр ҫул',
9260        yy: '%d ҫул',
9261    },
9262    dayOfMonthOrdinalParse: /\d{1,2}-мӗш/,
9263    ordinal: '%d-мӗш',
9264    week: {
9265        dow: 1, // Monday is the first day of the week.
9266        doy: 7, // The week that contains Jan 7th is the first week of the year.
9267    },
9268}));
9269
9270
9271/***/ }),
9272/* 30 */
9273/***/ (function(module, __webpack_exports__, __webpack_require__) {
9274
9275"use strict";
9276Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
9277/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
9278//! moment.js locale configuration
9279//! locale : Welsh [cy]
9280//! author : Robert Allen : https://github.com/robgallen
9281//! author : https://github.com/ryangreaves
9282
9283
9284
9285/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('cy', {
9286    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split(
9287        '_'
9288    ),
9289    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split(
9290        '_'
9291    ),
9292    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split(
9293        '_'
9294    ),
9295    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),
9296    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),
9297    weekdaysParseExact: true,
9298    // time formats are the same as en-gb
9299    longDateFormat: {
9300        LT: 'HH:mm',
9301        LTS: 'HH:mm:ss',
9302        L: 'DD/MM/YYYY',
9303        LL: 'D MMMM YYYY',
9304        LLL: 'D MMMM YYYY HH:mm',
9305        LLLL: 'dddd, D MMMM YYYY HH:mm',
9306    },
9307    calendar: {
9308        sameDay: '[Heddiw am] LT',
9309        nextDay: '[Yfory am] LT',
9310        nextWeek: 'dddd [am] LT',
9311        lastDay: '[Ddoe am] LT',
9312        lastWeek: 'dddd [diwethaf am] LT',
9313        sameElse: 'L',
9314    },
9315    relativeTime: {
9316        future: 'mewn %s',
9317        past: '%s yn ôl',
9318        s: 'ychydig eiliadau',
9319        ss: '%d eiliad',
9320        m: 'munud',
9321        mm: '%d munud',
9322        h: 'awr',
9323        hh: '%d awr',
9324        d: 'diwrnod',
9325        dd: '%d diwrnod',
9326        M: 'mis',
9327        MM: '%d mis',
9328        y: 'blwyddyn',
9329        yy: '%d flynedd',
9330    },
9331    dayOfMonthOrdinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,
9332    // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh
9333    ordinal: function (number) {
9334        var b = number,
9335            output = '',
9336            lookup = [
9337                '',
9338                'af',
9339                'il',
9340                'ydd',
9341                'ydd',
9342                'ed',
9343                'ed',
9344                'ed',
9345                'fed',
9346                'fed',
9347                'fed', // 1af to 10fed
9348                'eg',
9349                'fed',
9350                'eg',
9351                'eg',
9352                'fed',
9353                'eg',
9354                'eg',
9355                'fed',
9356                'eg',
9357                'fed', // 11eg to 20fed
9358            ];
9359        if (b > 20) {
9360            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {
9361                output = 'fed'; // not 30ain, 70ain or 90ain
9362            } else {
9363                output = 'ain';
9364            }
9365        } else if (b > 0) {
9366            output = lookup[b];
9367        }
9368        return number + output;
9369    },
9370    week: {
9371        dow: 1, // Monday is the first day of the week.
9372        doy: 4, // The week that contains Jan 4th is the first week of the year.
9373    },
9374}));
9375
9376
9377/***/ }),
9378/* 31 */
9379/***/ (function(module, __webpack_exports__, __webpack_require__) {
9380
9381"use strict";
9382Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
9383/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
9384//! moment.js locale configuration
9385//! locale : Danish [da]
9386//! author : Ulrik Nielsen : https://github.com/mrbase
9387
9388
9389
9390/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('da', {
9391    months: 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split(
9392        '_'
9393    ),
9394    monthsShort: 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
9395    weekdays: 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
9396    weekdaysShort: 'søn_man_tir_ons_tor_fre_lør'.split('_'),
9397    weekdaysMin: 'sø_ma_ti_on_to_fr_lø'.split('_'),
9398    longDateFormat: {
9399        LT: 'HH:mm',
9400        LTS: 'HH:mm:ss',
9401        L: 'DD.MM.YYYY',
9402        LL: 'D. MMMM YYYY',
9403        LLL: 'D. MMMM YYYY HH:mm',
9404        LLLL: 'dddd [d.] D. MMMM YYYY [kl.] HH:mm',
9405    },
9406    calendar: {
9407        sameDay: '[i dag kl.] LT',
9408        nextDay: '[i morgen kl.] LT',
9409        nextWeek: 'på dddd [kl.] LT',
9410        lastDay: '[i går kl.] LT',
9411        lastWeek: '[i] dddd[s kl.] LT',
9412        sameElse: 'L',
9413    },
9414    relativeTime: {
9415        future: 'om %s',
9416        past: '%s siden',
9417        s: 'få sekunder',
9418        ss: '%d sekunder',
9419        m: 'et minut',
9420        mm: '%d minutter',
9421        h: 'en time',
9422        hh: '%d timer',
9423        d: 'en dag',
9424        dd: '%d dage',
9425        M: 'en måned',
9426        MM: '%d måneder',
9427        y: 'et år',
9428        yy: '%d år',
9429    },
9430    dayOfMonthOrdinalParse: /\d{1,2}\./,
9431    ordinal: '%d.',
9432    week: {
9433        dow: 1, // Monday is the first day of the week.
9434        doy: 4, // The week that contains Jan 4th is the first week of the year.
9435    },
9436}));
9437
9438
9439/***/ }),
9440/* 32 */
9441/***/ (function(module, __webpack_exports__, __webpack_require__) {
9442
9443"use strict";
9444Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
9445/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
9446//! moment.js locale configuration
9447//! locale : German [de]
9448//! author : lluchs : https://github.com/lluchs
9449//! author: Menelion Elensúle: https://github.com/Oire
9450//! author : Mikolaj Dadela : https://github.com/mik01aj
9451
9452
9453
9454function processRelativeTime(number, withoutSuffix, key, isFuture) {
9455    var format = {
9456        m: ['eine Minute', 'einer Minute'],
9457        h: ['eine Stunde', 'einer Stunde'],
9458        d: ['ein Tag', 'einem Tag'],
9459        dd: [number + ' Tage', number + ' Tagen'],
9460        w: ['eine Woche', 'einer Woche'],
9461        M: ['ein Monat', 'einem Monat'],
9462        MM: [number + ' Monate', number + ' Monaten'],
9463        y: ['ein Jahr', 'einem Jahr'],
9464        yy: [number + ' Jahre', number + ' Jahren'],
9465    };
9466    return withoutSuffix ? format[key][0] : format[key][1];
9467}
9468
9469/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('de', {
9470    months: 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split(
9471        '_'
9472    ),
9473    monthsShort: 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split(
9474        '_'
9475    ),
9476    monthsParseExact: true,
9477    weekdays: 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split(
9478        '_'
9479    ),
9480    weekdaysShort: 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
9481    weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
9482    weekdaysParseExact: true,
9483    longDateFormat: {
9484        LT: 'HH:mm',
9485        LTS: 'HH:mm:ss',
9486        L: 'DD.MM.YYYY',
9487        LL: 'D. MMMM YYYY',
9488        LLL: 'D. MMMM YYYY HH:mm',
9489        LLLL: 'dddd, D. MMMM YYYY HH:mm',
9490    },
9491    calendar: {
9492        sameDay: '[heute um] LT [Uhr]',
9493        sameElse: 'L',
9494        nextDay: '[morgen um] LT [Uhr]',
9495        nextWeek: 'dddd [um] LT [Uhr]',
9496        lastDay: '[gestern um] LT [Uhr]',
9497        lastWeek: '[letzten] dddd [um] LT [Uhr]',
9498    },
9499    relativeTime: {
9500        future: 'in %s',
9501        past: 'vor %s',
9502        s: 'ein paar Sekunden',
9503        ss: '%d Sekunden',
9504        m: processRelativeTime,
9505        mm: '%d Minuten',
9506        h: processRelativeTime,
9507        hh: '%d Stunden',
9508        d: processRelativeTime,
9509        dd: processRelativeTime,
9510        w: processRelativeTime,
9511        ww: '%d Wochen',
9512        M: processRelativeTime,
9513        MM: processRelativeTime,
9514        y: processRelativeTime,
9515        yy: processRelativeTime,
9516    },
9517    dayOfMonthOrdinalParse: /\d{1,2}\./,
9518    ordinal: '%d.',
9519    week: {
9520        dow: 1, // Monday is the first day of the week.
9521        doy: 4, // The week that contains Jan 4th is the first week of the year.
9522    },
9523}));
9524
9525
9526/***/ }),
9527/* 33 */
9528/***/ (function(module, __webpack_exports__, __webpack_require__) {
9529
9530"use strict";
9531Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
9532/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
9533//! moment.js locale configuration
9534//! locale : German (Austria) [de-at]
9535//! author : lluchs : https://github.com/lluchs
9536//! author: Menelion Elensúle: https://github.com/Oire
9537//! author : Martin Groller : https://github.com/MadMG
9538//! author : Mikolaj Dadela : https://github.com/mik01aj
9539
9540
9541
9542function processRelativeTime(number, withoutSuffix, key, isFuture) {
9543    var format = {
9544        m: ['eine Minute', 'einer Minute'],
9545        h: ['eine Stunde', 'einer Stunde'],
9546        d: ['ein Tag', 'einem Tag'],
9547        dd: [number + ' Tage', number + ' Tagen'],
9548        w: ['eine Woche', 'einer Woche'],
9549        M: ['ein Monat', 'einem Monat'],
9550        MM: [number + ' Monate', number + ' Monaten'],
9551        y: ['ein Jahr', 'einem Jahr'],
9552        yy: [number + ' Jahre', number + ' Jahren'],
9553    };
9554    return withoutSuffix ? format[key][0] : format[key][1];
9555}
9556
9557/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('de-at', {
9558    months: 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split(
9559        '_'
9560    ),
9561    monthsShort: 'Jän._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split(
9562        '_'
9563    ),
9564    monthsParseExact: true,
9565    weekdays: 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split(
9566        '_'
9567    ),
9568    weekdaysShort: 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
9569    weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
9570    weekdaysParseExact: true,
9571    longDateFormat: {
9572        LT: 'HH:mm',
9573        LTS: 'HH:mm:ss',
9574        L: 'DD.MM.YYYY',
9575        LL: 'D. MMMM YYYY',
9576        LLL: 'D. MMMM YYYY HH:mm',
9577        LLLL: 'dddd, D. MMMM YYYY HH:mm',
9578    },
9579    calendar: {
9580        sameDay: '[heute um] LT [Uhr]',
9581        sameElse: 'L',
9582        nextDay: '[morgen um] LT [Uhr]',
9583        nextWeek: 'dddd [um] LT [Uhr]',
9584        lastDay: '[gestern um] LT [Uhr]',
9585        lastWeek: '[letzten] dddd [um] LT [Uhr]',
9586    },
9587    relativeTime: {
9588        future: 'in %s',
9589        past: 'vor %s',
9590        s: 'ein paar Sekunden',
9591        ss: '%d Sekunden',
9592        m: processRelativeTime,
9593        mm: '%d Minuten',
9594        h: processRelativeTime,
9595        hh: '%d Stunden',
9596        d: processRelativeTime,
9597        dd: processRelativeTime,
9598        w: processRelativeTime,
9599        ww: '%d Wochen',
9600        M: processRelativeTime,
9601        MM: processRelativeTime,
9602        y: processRelativeTime,
9603        yy: processRelativeTime,
9604    },
9605    dayOfMonthOrdinalParse: /\d{1,2}\./,
9606    ordinal: '%d.',
9607    week: {
9608        dow: 1, // Monday is the first day of the week.
9609        doy: 4, // The week that contains Jan 4th is the first week of the year.
9610    },
9611}));
9612
9613
9614/***/ }),
9615/* 34 */
9616/***/ (function(module, __webpack_exports__, __webpack_require__) {
9617
9618"use strict";
9619Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
9620/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
9621//! moment.js locale configuration
9622//! locale : German (Switzerland) [de-ch]
9623//! author : sschueller : https://github.com/sschueller
9624
9625// based on: https://www.bk.admin.ch/dokumentation/sprachen/04915/05016/index.html?lang=de#
9626
9627
9628
9629function processRelativeTime(number, withoutSuffix, key, isFuture) {
9630    var format = {
9631        m: ['eine Minute', 'einer Minute'],
9632        h: ['eine Stunde', 'einer Stunde'],
9633        d: ['ein Tag', 'einem Tag'],
9634        dd: [number + ' Tage', number + ' Tagen'],
9635        w: ['eine Woche', 'einer Woche'],
9636        M: ['ein Monat', 'einem Monat'],
9637        MM: [number + ' Monate', number + ' Monaten'],
9638        y: ['ein Jahr', 'einem Jahr'],
9639        yy: [number + ' Jahre', number + ' Jahren'],
9640    };
9641    return withoutSuffix ? format[key][0] : format[key][1];
9642}
9643
9644/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('de-ch', {
9645    months: 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split(
9646        '_'
9647    ),
9648    monthsShort: 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split(
9649        '_'
9650    ),
9651    monthsParseExact: true,
9652    weekdays: 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split(
9653        '_'
9654    ),
9655    weekdaysShort: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
9656    weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
9657    weekdaysParseExact: true,
9658    longDateFormat: {
9659        LT: 'HH:mm',
9660        LTS: 'HH:mm:ss',
9661        L: 'DD.MM.YYYY',
9662        LL: 'D. MMMM YYYY',
9663        LLL: 'D. MMMM YYYY HH:mm',
9664        LLLL: 'dddd, D. MMMM YYYY HH:mm',
9665    },
9666    calendar: {
9667        sameDay: '[heute um] LT [Uhr]',
9668        sameElse: 'L',
9669        nextDay: '[morgen um] LT [Uhr]',
9670        nextWeek: 'dddd [um] LT [Uhr]',
9671        lastDay: '[gestern um] LT [Uhr]',
9672        lastWeek: '[letzten] dddd [um] LT [Uhr]',
9673    },
9674    relativeTime: {
9675        future: 'in %s',
9676        past: 'vor %s',
9677        s: 'ein paar Sekunden',
9678        ss: '%d Sekunden',
9679        m: processRelativeTime,
9680        mm: '%d Minuten',
9681        h: processRelativeTime,
9682        hh: '%d Stunden',
9683        d: processRelativeTime,
9684        dd: processRelativeTime,
9685        w: processRelativeTime,
9686        ww: '%d Wochen',
9687        M: processRelativeTime,
9688        MM: processRelativeTime,
9689        y: processRelativeTime,
9690        yy: processRelativeTime,
9691    },
9692    dayOfMonthOrdinalParse: /\d{1,2}\./,
9693    ordinal: '%d.',
9694    week: {
9695        dow: 1, // Monday is the first day of the week.
9696        doy: 4, // The week that contains Jan 4th is the first week of the year.
9697    },
9698}));
9699
9700
9701/***/ }),
9702/* 35 */
9703/***/ (function(module, __webpack_exports__, __webpack_require__) {
9704
9705"use strict";
9706Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
9707/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
9708//! moment.js locale configuration
9709//! locale : Maldivian [dv]
9710//! author : Jawish Hameed : https://github.com/jawish
9711
9712
9713
9714var months = [
9715        'ޖެނުއަރީ',
9716        'ފެބްރުއަރީ',
9717        'މާރިޗު',
9718        'އޭޕްރީލު',
9719        'މޭ',
9720        'ޖޫން',
9721        'ޖުލައި',
9722        'އޯގަސްޓު',
9723        'ސެޕްޓެމްބަރު',
9724        'އޮކްޓޯބަރު',
9725        'ނޮވެމްބަރު',
9726        'ޑިސެމްބަރު',
9727    ],
9728    weekdays = [
9729        'އާދިއްތަ',
9730        'ހޯމަ',
9731        'އަންގާރަ',
9732        'ބުދަ',
9733        'ބުރާސްފަތި',
9734        'ހުކުރު',
9735        'ހޮނިހިރު',
9736    ];
9737
9738/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('dv', {
9739    months: months,
9740    monthsShort: months,
9741    weekdays: weekdays,
9742    weekdaysShort: weekdays,
9743    weekdaysMin: 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),
9744    longDateFormat: {
9745        LT: 'HH:mm',
9746        LTS: 'HH:mm:ss',
9747        L: 'D/M/YYYY',
9748        LL: 'D MMMM YYYY',
9749        LLL: 'D MMMM YYYY HH:mm',
9750        LLLL: 'dddd D MMMM YYYY HH:mm',
9751    },
9752    meridiemParse: /މކ|މފ/,
9753    isPM: function (input) {
9754        return 'މފ' === input;
9755    },
9756    meridiem: function (hour, minute, isLower) {
9757        if (hour < 12) {
9758            return 'މކ';
9759        } else {
9760            return 'މފ';
9761        }
9762    },
9763    calendar: {
9764        sameDay: '[މިއަދު] LT',
9765        nextDay: '[މާދަމާ] LT',
9766        nextWeek: 'dddd LT',
9767        lastDay: '[އިއްޔެ] LT',
9768        lastWeek: '[ފާއިތުވި] dddd LT',
9769        sameElse: 'L',
9770    },
9771    relativeTime: {
9772        future: 'ތެރޭގައި %s',
9773        past: 'ކުރިން %s',
9774        s: 'ސިކުންތުކޮޅެއް',
9775        ss: 'd% ސިކުންތު',
9776        m: 'މިނިޓެއް',
9777        mm: 'މިނިޓު %d',
9778        h: 'ގަޑިއިރެއް',
9779        hh: 'ގަޑިއިރު %d',
9780        d: 'ދުވަހެއް',
9781        dd: 'ދުވަސް %d',
9782        M: 'މަހެއް',
9783        MM: 'މަސް %d',
9784        y: 'އަހަރެއް',
9785        yy: 'އަހަރު %d',
9786    },
9787    preparse: function (string) {
9788        return string.replace(/،/g, ',');
9789    },
9790    postformat: function (string) {
9791        return string.replace(/,/g, '،');
9792    },
9793    week: {
9794        dow: 7, // Sunday is the first day of the week.
9795        doy: 12, // The week that contains Jan 12th is the first week of the year.
9796    },
9797}));
9798
9799
9800/***/ }),
9801/* 36 */
9802/***/ (function(module, __webpack_exports__, __webpack_require__) {
9803
9804"use strict";
9805Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
9806/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
9807//! moment.js locale configuration
9808//! locale : Greek [el]
9809//! author : Aggelos Karalias : https://github.com/mehiel
9810
9811
9812
9813function isFunction(input) {
9814    return (
9815        (typeof Function !== 'undefined' && input instanceof Function) ||
9816        Object.prototype.toString.call(input) === '[object Function]'
9817    );
9818}
9819
9820/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('el', {
9821    monthsNominativeEl: 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split(
9822        '_'
9823    ),
9824    monthsGenitiveEl: 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split(
9825        '_'
9826    ),
9827    months: function (momentToFormat, format) {
9828        if (!momentToFormat) {
9829            return this._monthsNominativeEl;
9830        } else if (
9831            typeof format === 'string' &&
9832            /D/.test(format.substring(0, format.indexOf('MMMM')))
9833        ) {
9834            // if there is a day number before 'MMMM'
9835            return this._monthsGenitiveEl[momentToFormat.month()];
9836        } else {
9837            return this._monthsNominativeEl[momentToFormat.month()];
9838        }
9839    },
9840    monthsShort: 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),
9841    weekdays: 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split(
9842        '_'
9843    ),
9844    weekdaysShort: 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),
9845    weekdaysMin: 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),
9846    meridiem: function (hours, minutes, isLower) {
9847        if (hours > 11) {
9848            return isLower ? 'μμ' : 'ΜΜ';
9849        } else {
9850            return isLower ? 'πμ' : 'ΠΜ';
9851        }
9852    },
9853    isPM: function (input) {
9854        return (input + '').toLowerCase()[0] === 'μ';
9855    },
9856    meridiemParse: /[ΠΜ]\.?Μ?\.?/i,
9857    longDateFormat: {
9858        LT: 'h:mm A',
9859        LTS: 'h:mm:ss A',
9860        L: 'DD/MM/YYYY',
9861        LL: 'D MMMM YYYY',
9862        LLL: 'D MMMM YYYY h:mm A',
9863        LLLL: 'dddd, D MMMM YYYY h:mm A',
9864    },
9865    calendarEl: {
9866        sameDay: '[Σήμερα {}] LT',
9867        nextDay: '[Αύριο {}] LT',
9868        nextWeek: 'dddd [{}] LT',
9869        lastDay: '[Χθες {}] LT',
9870        lastWeek: function () {
9871            switch (this.day()) {
9872                case 6:
9873                    return '[το προηγούμενο] dddd [{}] LT';
9874                default:
9875                    return '[την προηγούμενη] dddd [{}] LT';
9876            }
9877        },
9878        sameElse: 'L',
9879    },
9880    calendar: function (key, mom) {
9881        var output = this._calendarEl[key],
9882            hours = mom && mom.hours();
9883        if (isFunction(output)) {
9884            output = output.apply(mom);
9885        }
9886        return output.replace('{}', hours % 12 === 1 ? 'στη' : 'στις');
9887    },
9888    relativeTime: {
9889        future: 'σε %s',
9890        past: '%s πριν',
9891        s: 'λίγα δευτερόλεπτα',
9892        ss: '%d δευτερόλεπτα',
9893        m: 'ένα λεπτό',
9894        mm: '%d λεπτά',
9895        h: 'μία ώρα',
9896        hh: '%d ώρες',
9897        d: 'μία μέρα',
9898        dd: '%d μέρες',
vendor: 16,384 bytes, lines 9899-10433
9899        M: 'ένας μήνας',
9900        MM: '%d μήνες',
9901        y: 'ένας χρόνος',
9902        yy: '%d χρόνια',
9903    },
9904    dayOfMonthOrdinalParse: /\d{1,2}η/,
9905    ordinal: '%dη',
9906    week: {
9907        dow: 1, // Monday is the first day of the week.
9908        doy: 4, // The week that contains Jan 4st is the first week of the year.
9909    },
9910}));
9911
9912
9913/***/ }),
9914/* 37 */
9915/***/ (function(module, __webpack_exports__, __webpack_require__) {
9916
9917"use strict";
9918Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
9919/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
9920//! moment.js locale configuration
9921//! locale : English (Australia) [en-au]
9922//! author : Jared Morse : https://github.com/jarcoal
9923
9924
9925
9926/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('en-au', {
9927    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
9928        '_'
9929    ),
9930    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
9931    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
9932        '_'
9933    ),
9934    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
9935    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
9936    longDateFormat: {
9937        LT: 'h:mm A',
9938        LTS: 'h:mm:ss A',
9939        L: 'DD/MM/YYYY',
9940        LL: 'D MMMM YYYY',
9941        LLL: 'D MMMM YYYY h:mm A',
9942        LLLL: 'dddd, D MMMM YYYY h:mm A',
9943    },
9944    calendar: {
9945        sameDay: '[Today at] LT',
9946        nextDay: '[Tomorrow at] LT',
9947        nextWeek: 'dddd [at] LT',
9948        lastDay: '[Yesterday at] LT',
9949        lastWeek: '[Last] dddd [at] LT',
9950        sameElse: 'L',
9951    },
9952    relativeTime: {
9953        future: 'in %s',
9954        past: '%s ago',
9955        s: 'a few seconds',
9956        ss: '%d seconds',
9957        m: 'a minute',
9958        mm: '%d minutes',
9959        h: 'an hour',
9960        hh: '%d hours',
9961        d: 'a day',
9962        dd: '%d days',
9963        M: 'a month',
9964        MM: '%d months',
9965        y: 'a year',
9966        yy: '%d years',
9967    },
9968    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
9969    ordinal: function (number) {
9970        var b = number % 10,
9971            output =
9972                ~~((number % 100) / 10) === 1
9973                    ? 'th'
9974                    : b === 1
9975                    ? 'st'
9976                    : b === 2
9977                    ? 'nd'
9978                    : b === 3
9979                    ? 'rd'
9980                    : 'th';
9981        return number + output;
9982    },
9983    week: {
9984        dow: 0, // Sunday is the first day of the week.
9985        doy: 4, // The week that contains Jan 4th is the first week of the year.
9986    },
9987}));
9988
9989
9990/***/ }),
9991/* 38 */
9992/***/ (function(module, __webpack_exports__, __webpack_require__) {
9993
9994"use strict";
9995Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
9996/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
9997//! moment.js locale configuration
9998//! locale : English (Canada) [en-ca]
9999//! author : Jonathan Abourbih : https://github.com/jonbca
10000
10001
10002
10003/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('en-ca', {
10004    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
10005        '_'
10006    ),
10007    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
10008    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
10009        '_'
10010    ),
10011    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
10012    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
10013    longDateFormat: {
10014        LT: 'h:mm A',
10015        LTS: 'h:mm:ss A',
10016        L: 'YYYY-MM-DD',
10017        LL: 'MMMM D, YYYY',
10018        LLL: 'MMMM D, YYYY h:mm A',
10019        LLLL: 'dddd, MMMM D, YYYY h:mm A',
10020    },
10021    calendar: {
10022        sameDay: '[Today at] LT',
10023        nextDay: '[Tomorrow at] LT',
10024        nextWeek: 'dddd [at] LT',
10025        lastDay: '[Yesterday at] LT',
10026        lastWeek: '[Last] dddd [at] LT',
10027        sameElse: 'L',
10028    },
10029    relativeTime: {
10030        future: 'in %s',
10031        past: '%s ago',
10032        s: 'a few seconds',
10033        ss: '%d seconds',
10034        m: 'a minute',
10035        mm: '%d minutes',
10036        h: 'an hour',
10037        hh: '%d hours',
10038        d: 'a day',
10039        dd: '%d days',
10040        M: 'a month',
10041        MM: '%d months',
10042        y: 'a year',
10043        yy: '%d years',
10044    },
10045    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
10046    ordinal: function (number) {
10047        var b = number % 10,
10048            output =
10049                ~~((number % 100) / 10) === 1
10050                    ? 'th'
10051                    : b === 1
10052                    ? 'st'
10053                    : b === 2
10054                    ? 'nd'
10055                    : b === 3
10056                    ? 'rd'
10057                    : 'th';
10058        return number + output;
10059    },
10060}));
10061
10062
10063/***/ }),
10064/* 39 */
10065/***/ (function(module, __webpack_exports__, __webpack_require__) {
10066
10067"use strict";
10068Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
10069/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
10070//! moment.js locale configuration
10071//! locale : English (United Kingdom) [en-gb]
10072//! author : Chris Gedrim : https://github.com/chrisgedrim
10073
10074
10075
10076/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('en-gb', {
10077    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
10078        '_'
10079    ),
10080    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
10081    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
10082        '_'
10083    ),
10084    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
10085    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
10086    longDateFormat: {
10087        LT: 'HH:mm',
10088        LTS: 'HH:mm:ss',
10089        L: 'DD/MM/YYYY',
10090        LL: 'D MMMM YYYY',
10091        LLL: 'D MMMM YYYY HH:mm',
10092        LLLL: 'dddd, D MMMM YYYY HH:mm',
10093    },
10094    calendar: {
10095        sameDay: '[Today at] LT',
10096        nextDay: '[Tomorrow at] LT',
10097        nextWeek: 'dddd [at] LT',
10098        lastDay: '[Yesterday at] LT',
10099        lastWeek: '[Last] dddd [at] LT',
10100        sameElse: 'L',
10101    },
10102    relativeTime: {
10103        future: 'in %s',
10104        past: '%s ago',
10105        s: 'a few seconds',
10106        ss: '%d seconds',
10107        m: 'a minute',
10108        mm: '%d minutes',
10109        h: 'an hour',
10110        hh: '%d hours',
10111        d: 'a day',
10112        dd: '%d days',
10113        M: 'a month',
10114        MM: '%d months',
10115        y: 'a year',
10116        yy: '%d years',
10117    },
10118    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
10119    ordinal: function (number) {
10120        var b = number % 10,
10121            output =
10122                ~~((number % 100) / 10) === 1
10123                    ? 'th'
10124                    : b === 1
10125                    ? 'st'
10126                    : b === 2
10127                    ? 'nd'
10128                    : b === 3
10129                    ? 'rd'
10130                    : 'th';
10131        return number + output;
10132    },
10133    week: {
10134        dow: 1, // Monday is the first day of the week.
10135        doy: 4, // The week that contains Jan 4th is the first week of the year.
10136    },
10137}));
10138
10139
10140/***/ }),
10141/* 40 */
10142/***/ (function(module, __webpack_exports__, __webpack_require__) {
10143
10144"use strict";
10145Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
10146/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
10147//! moment.js locale configuration
10148//! locale : English (Ireland) [en-ie]
10149//! author : Chris Cartlidge : https://github.com/chriscartlidge
10150
10151
10152
10153/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('en-ie', {
10154    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
10155        '_'
10156    ),
10157    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
10158    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
10159        '_'
10160    ),
10161    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
10162    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
10163    longDateFormat: {
10164        LT: 'HH:mm',
10165        LTS: 'HH:mm:ss',
10166        L: 'DD/MM/YYYY',
10167        LL: 'D MMMM YYYY',
10168        LLL: 'D MMMM YYYY HH:mm',
10169        LLLL: 'dddd D MMMM YYYY HH:mm',
10170    },
10171    calendar: {
10172        sameDay: '[Today at] LT',
10173        nextDay: '[Tomorrow at] LT',
10174        nextWeek: 'dddd [at] LT',
10175        lastDay: '[Yesterday at] LT',
10176        lastWeek: '[Last] dddd [at] LT',
10177        sameElse: 'L',
10178    },
10179    relativeTime: {
10180        future: 'in %s',
10181        past: '%s ago',
10182        s: 'a few seconds',
10183        ss: '%d seconds',
10184        m: 'a minute',
10185        mm: '%d minutes',
10186        h: 'an hour',
10187        hh: '%d hours',
10188        d: 'a day',
10189        dd: '%d days',
10190        M: 'a month',
10191        MM: '%d months',
10192        y: 'a year',
10193        yy: '%d years',
10194    },
10195    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
10196    ordinal: function (number) {
10197        var b = number % 10,
10198            output =
10199                ~~((number % 100) / 10) === 1
10200                    ? 'th'
10201                    : b === 1
10202                    ? 'st'
10203                    : b === 2
10204                    ? 'nd'
10205                    : b === 3
10206                    ? 'rd'
10207                    : 'th';
10208        return number + output;
10209    },
10210    week: {
10211        dow: 1, // Monday is the first day of the week.
10212        doy: 4, // The week that contains Jan 4th is the first week of the year.
10213    },
10214}));
10215
10216
10217/***/ }),
10218/* 41 */
10219/***/ (function(module, __webpack_exports__, __webpack_require__) {
10220
10221"use strict";
10222Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
10223/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
10224//! moment.js locale configuration
10225//! locale : English (Israel) [en-il]
10226//! author : Chris Gedrim : https://github.com/chrisgedrim
10227
10228
10229
10230/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('en-il', {
10231    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
10232        '_'
10233    ),
10234    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
10235    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
10236        '_'
10237    ),
10238    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
10239    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
10240    longDateFormat: {
10241        LT: 'HH:mm',
10242        LTS: 'HH:mm:ss',
10243        L: 'DD/MM/YYYY',
10244        LL: 'D MMMM YYYY',
10245        LLL: 'D MMMM YYYY HH:mm',
10246        LLLL: 'dddd, D MMMM YYYY HH:mm',
10247    },
10248    calendar: {
10249        sameDay: '[Today at] LT',
10250        nextDay: '[Tomorrow at] LT',
10251        nextWeek: 'dddd [at] LT',
10252        lastDay: '[Yesterday at] LT',
10253        lastWeek: '[Last] dddd [at] LT',
10254        sameElse: 'L',
10255    },
10256    relativeTime: {
10257        future: 'in %s',
10258        past: '%s ago',
10259        s: 'a few seconds',
10260        ss: '%d seconds',
10261        m: 'a minute',
10262        mm: '%d minutes',
10263        h: 'an hour',
10264        hh: '%d hours',
10265        d: 'a day',
10266        dd: '%d days',
10267        M: 'a month',
10268        MM: '%d months',
10269        y: 'a year',
10270        yy: '%d years',
10271    },
10272    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
10273    ordinal: function (number) {
10274        var b = number % 10,
10275            output =
10276                ~~((number % 100) / 10) === 1
10277                    ? 'th'
10278                    : b === 1
10279                    ? 'st'
10280                    : b === 2
10281                    ? 'nd'
10282                    : b === 3
10283                    ? 'rd'
10284                    : 'th';
10285        return number + output;
10286    },
10287}));
10288
10289
10290/***/ }),
10291/* 42 */
10292/***/ (function(module, __webpack_exports__, __webpack_require__) {
10293
10294"use strict";
10295Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
10296/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
10297//! moment.js locale configuration
10298//! locale : English (India) [en-in]
10299//! author : Jatin Agrawal : https://github.com/jatinag22
10300
10301
10302
10303/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('en-in', {
10304    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
10305        '_'
10306    ),
10307    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
10308    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
10309        '_'
10310    ),
10311    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
10312    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
10313    longDateFormat: {
10314        LT: 'h:mm A',
10315        LTS: 'h:mm:ss A',
10316        L: 'DD/MM/YYYY',
10317        LL: 'D MMMM YYYY',
10318        LLL: 'D MMMM YYYY h:mm A',
10319        LLLL: 'dddd, D MMMM YYYY h:mm A',
10320    },
10321    calendar: {
10322        sameDay: '[Today at] LT',
10323        nextDay: '[Tomorrow at] LT',
10324        nextWeek: 'dddd [at] LT',
10325        lastDay: '[Yesterday at] LT',
10326        lastWeek: '[Last] dddd [at] LT',
10327        sameElse: 'L',
10328    },
10329    relativeTime: {
10330        future: 'in %s',
10331        past: '%s ago',
10332        s: 'a few seconds',
10333        ss: '%d seconds',
10334        m: 'a minute',
10335        mm: '%d minutes',
10336        h: 'an hour',
10337        hh: '%d hours',
10338        d: 'a day',
10339        dd: '%d days',
10340        M: 'a month',
10341        MM: '%d months',
10342        y: 'a year',
10343        yy: '%d years',
10344    },
10345    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
10346    ordinal: function (number) {
10347        var b = number % 10,
10348            output =
10349                ~~((number % 100) / 10) === 1
10350                    ? 'th'
10351                    : b === 1
10352                    ? 'st'
10353                    : b === 2
10354                    ? 'nd'
10355                    : b === 3
10356                    ? 'rd'
10357                    : 'th';
10358        return number + output;
10359    },
10360    week: {
10361        dow: 0, // Sunday is the first day of the week.
10362        doy: 6, // The week that contains Jan 1st is the first week of the year.
10363    },
10364}));
10365
10366
10367/***/ }),
10368/* 43 */
10369/***/ (function(module, __webpack_exports__, __webpack_require__) {
10370
10371"use strict";
10372Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
10373/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
10374//! moment.js locale configuration
10375//! locale : English (New Zealand) [en-nz]
10376//! author : Luke McGregor : https://github.com/lukemcgregor
10377
10378
10379
10380/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('en-nz', {
10381    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
10382        '_'
10383    ),
10384    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
10385    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
10386        '_'
10387    ),
10388    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
10389    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
10390    longDateFormat: {
10391        LT: 'h:mm A',
10392        LTS: 'h:mm:ss A',
10393        L: 'DD/MM/YYYY',
10394        LL: 'D MMMM YYYY',
10395        LLL: 'D MMMM YYYY h:mm A',
10396        LLLL: 'dddd, D MMMM YYYY h:mm A',
10397    },
10398    calendar: {
10399        sameDay: '[Today at] LT',
10400        nextDay: '[Tomorrow at] LT',
10401        nextWeek: 'dddd [at] LT',
10402        lastDay: '[Yesterday at] LT',
10403        lastWeek: '[Last] dddd [at] LT',
10404        sameElse: 'L',
10405    },
10406    relativeTime: {
10407        future: 'in %s',
10408        past: '%s ago',
10409        s: 'a few seconds',
10410        ss: '%d seconds',
10411        m: 'a minute',
10412        mm: '%d minutes',
10413        h: 'an hour',
10414        hh: '%d hours',
10415        d: 'a day',
10416        dd: '%d days',
10417        M: 'a month',
10418        MM: '%d months',
10419        y: 'a year',
10420        yy: '%d years',
10421    },
10422    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
10423    ordinal: function (number) {
10424        var b = number % 10,
10425            output =
10426                ~~((number % 100) / 10) === 1
10427                    ? 'th'
10428                    : b === 1
10429                    ? 'st'
10430                    : b === 2
10431                    ? 'nd'
10432                    : b === 3
10433              
vendor: 20,799 bytes, lines 10433-11064
10433      ? 'rd'
10434                    : 'th';
10435        return number + output;
10436    },
10437    week: {
10438        dow: 1, // Monday is the first day of the week.
10439        doy: 4, // The week that contains Jan 4th is the first week of the year.
10440    },
10441}));
10442
10443
10444/***/ }),
10445/* 44 */
10446/***/ (function(module, __webpack_exports__, __webpack_require__) {
10447
10448"use strict";
10449Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
10450/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
10451//! moment.js locale configuration
10452//! locale : English (Singapore) [en-sg]
10453//! author : Matthew Castrillon-Madrigal : https://github.com/techdimension
10454
10455
10456
10457/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('en-sg', {
10458    months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split(
10459        '_'
10460    ),
10461    monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
10462    weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split(
10463        '_'
10464    ),
10465    weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
10466    weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
10467    longDateFormat: {
10468        LT: 'HH:mm',
10469        LTS: 'HH:mm:ss',
10470        L: 'DD/MM/YYYY',
10471        LL: 'D MMMM YYYY',
10472        LLL: 'D MMMM YYYY HH:mm',
10473        LLLL: 'dddd, D MMMM YYYY HH:mm',
10474    },
10475    calendar: {
10476        sameDay: '[Today at] LT',
10477        nextDay: '[Tomorrow at] LT',
10478        nextWeek: 'dddd [at] LT',
10479        lastDay: '[Yesterday at] LT',
10480        lastWeek: '[Last] dddd [at] LT',
10481        sameElse: 'L',
10482    },
10483    relativeTime: {
10484        future: 'in %s',
10485        past: '%s ago',
10486        s: 'a few seconds',
10487        ss: '%d seconds',
10488        m: 'a minute',
10489        mm: '%d minutes',
10490        h: 'an hour',
10491        hh: '%d hours',
10492        d: 'a day',
10493        dd: '%d days',
10494        M: 'a month',
10495        MM: '%d months',
10496        y: 'a year',
10497        yy: '%d years',
10498    },
10499    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
10500    ordinal: function (number) {
10501        var b = number % 10,
10502            output =
10503                ~~((number % 100) / 10) === 1
10504                    ? 'th'
10505                    : b === 1
10506                    ? 'st'
10507                    : b === 2
10508                    ? 'nd'
10509                    : b === 3
10510                    ? 'rd'
10511                    : 'th';
10512        return number + output;
10513    },
10514    week: {
10515        dow: 1, // Monday is the first day of the week.
10516        doy: 4, // The week that contains Jan 4th is the first week of the year.
10517    },
10518}));
10519
10520
10521/***/ }),
10522/* 45 */
10523/***/ (function(module, __webpack_exports__, __webpack_require__) {
10524
10525"use strict";
10526Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
10527/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
10528//! moment.js locale configuration
10529//! locale : Esperanto [eo]
10530//! author : Colin Dean : https://github.com/colindean
10531//! author : Mia Nordentoft Imperatori : https://github.com/miestasmia
10532//! comment : miestasmia corrected the translation by colindean
10533//! comment : Vivakvo corrected the translation by colindean and miestasmia
10534
10535
10536
10537/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('eo', {
10538    months: 'januaro_februaro_marto_aprilo_majo_junio_julio_aÅ­gusto_septembro_oktobro_novembro_decembro'.split(
10539        '_'
10540    ),
10541    monthsShort: 'jan_feb_mart_apr_maj_jun_jul_aÅ­g_sept_okt_nov_dec'.split('_'),
10542    weekdays: 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'),
10543    weekdaysShort: 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'),
10544    weekdaysMin: 'di_lu_ma_me_ĵa_ve_sa'.split('_'),
10545    longDateFormat: {
10546        LT: 'HH:mm',
10547        LTS: 'HH:mm:ss',
10548        L: 'YYYY-MM-DD',
10549        LL: '[la] D[-an de] MMMM, YYYY',
10550        LLL: '[la] D[-an de] MMMM, YYYY HH:mm',
10551        LLLL: 'dddd[n], [la] D[-an de] MMMM, YYYY HH:mm',
10552        llll: 'ddd, [la] D[-an de] MMM, YYYY HH:mm',
10553    },
10554    meridiemParse: /[ap]\.t\.m/i,
10555    isPM: function (input) {
10556        return input.charAt(0).toLowerCase() === 'p';
10557    },
10558    meridiem: function (hours, minutes, isLower) {
10559        if (hours > 11) {
10560            return isLower ? 'p.t.m.' : 'P.T.M.';
10561        } else {
10562            return isLower ? 'a.t.m.' : 'A.T.M.';
10563        }
10564    },
10565    calendar: {
10566        sameDay: '[HodiaÅ­ je] LT',
10567        nextDay: '[MorgaÅ­ je] LT',
10568        nextWeek: 'dddd[n je] LT',
10569        lastDay: '[HieraÅ­ je] LT',
10570        lastWeek: '[pasintan] dddd[n je] LT',
10571        sameElse: 'L',
10572    },
10573    relativeTime: {
10574        future: 'post %s',
10575        past: 'antaÅ­ %s',
10576        s: 'kelkaj sekundoj',
10577        ss: '%d sekundoj',
10578        m: 'unu minuto',
10579        mm: '%d minutoj',
10580        h: 'unu horo',
10581        hh: '%d horoj',
10582        d: 'unu tago', //ne 'diurno', ĉar estas uzita por proksimumo
10583        dd: '%d tagoj',
10584        M: 'unu monato',
10585        MM: '%d monatoj',
10586        y: 'unu jaro',
10587        yy: '%d jaroj',
10588    },
10589    dayOfMonthOrdinalParse: /\d{1,2}a/,
10590    ordinal: '%da',
10591    week: {
10592        dow: 1, // Monday is the first day of the week.
10593        doy: 7, // The week that contains Jan 7th is the first week of the year.
10594    },
10595}));
10596
10597
10598/***/ }),
10599/* 46 */
10600/***/ (function(module, __webpack_exports__, __webpack_require__) {
10601
10602"use strict";
10603Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
10604/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
10605//! moment.js locale configuration
10606//! locale : Spanish [es]
10607//! author : Julio Napurí : https://github.com/julionc
10608
10609
10610
10611var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split(
10612        '_'
10613    ),
10614    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'),
10615    monthsParse = [
10616        /^ene/i,
10617        /^feb/i,
10618        /^mar/i,
10619        /^abr/i,
10620        /^may/i,
10621        /^jun/i,
10622        /^jul/i,
10623        /^ago/i,
10624        /^sep/i,
10625        /^oct/i,
10626        /^nov/i,
10627        /^dic/i,
10628    ],
10629    monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;
10630
10631/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('es', {
10632    months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split(
10633        '_'
10634    ),
10635    monthsShort: function (m, format) {
10636        if (!m) {
10637            return monthsShortDot;
10638        } else if (/-MMM-/.test(format)) {
10639            return monthsShort[m.month()];
10640        } else {
10641            return monthsShortDot[m.month()];
10642        }
10643    },
10644    monthsRegex: monthsRegex,
10645    monthsShortRegex: monthsRegex,
10646    monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,
10647    monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,
10648    monthsParse: monthsParse,
10649    longMonthsParse: monthsParse,
10650    shortMonthsParse: monthsParse,
10651    weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
10652    weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
10653    weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'),
10654    weekdaysParseExact: true,
10655    longDateFormat: {
10656        LT: 'H:mm',
10657        LTS: 'H:mm:ss',
10658        L: 'DD/MM/YYYY',
10659        LL: 'D [de] MMMM [de] YYYY',
10660        LLL: 'D [de] MMMM [de] YYYY H:mm',
10661        LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm',
10662    },
10663    calendar: {
10664        sameDay: function () {
10665            return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
10666        },
10667        nextDay: function () {
10668            return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
10669        },
10670        nextWeek: function () {
10671            return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
10672        },
10673        lastDay: function () {
10674            return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
10675        },
10676        lastWeek: function () {
10677            return (
10678                '[el] dddd [pasado a la' +
10679                (this.hours() !== 1 ? 's' : '') +
10680                '] LT'
10681            );
10682        },
10683        sameElse: 'L',
10684    },
10685    relativeTime: {
10686        future: 'en %s',
10687        past: 'hace %s',
10688        s: 'unos segundos',
10689        ss: '%d segundos',
10690        m: 'un minuto',
10691        mm: '%d minutos',
10692        h: 'una hora',
10693        hh: '%d horas',
10694        d: 'un día',
10695        dd: '%d días',
10696        w: 'una semana',
10697        ww: '%d semanas',
10698        M: 'un mes',
10699        MM: '%d meses',
10700        y: 'un año',
10701        yy: '%d años',
10702    },
10703    dayOfMonthOrdinalParse: /\d{1,2}º/,
10704    ordinal: '%dº',
10705    week: {
10706        dow: 1, // Monday is the first day of the week.
10707        doy: 4, // The week that contains Jan 4th is the first week of the year.
10708    },
10709    invalidDate: 'Fecha inválida',
10710}));
10711
10712
10713/***/ }),
10714/* 47 */
10715/***/ (function(module, __webpack_exports__, __webpack_require__) {
10716
10717"use strict";
10718Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
10719/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
10720//! moment.js locale configuration
10721//! locale : Spanish (Dominican Republic) [es-do]
10722
10723
10724
10725var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split(
10726        '_'
10727    ),
10728    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'),
10729    monthsParse = [
10730        /^ene/i,
10731        /^feb/i,
10732        /^mar/i,
10733        /^abr/i,
10734        /^may/i,
10735        /^jun/i,
10736        /^jul/i,
10737        /^ago/i,
10738        /^sep/i,
10739        /^oct/i,
10740        /^nov/i,
10741        /^dic/i,
10742    ],
10743    monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;
10744
10745/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('es-do', {
10746    months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split(
10747        '_'
10748    ),
10749    monthsShort: function (m, format) {
10750        if (!m) {
10751            return monthsShortDot;
10752        } else if (/-MMM-/.test(format)) {
10753            return monthsShort[m.month()];
10754        } else {
10755            return monthsShortDot[m.month()];
10756        }
10757    },
10758    monthsRegex: monthsRegex,
10759    monthsShortRegex: monthsRegex,
10760    monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,
10761    monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,
10762    monthsParse: monthsParse,
10763    longMonthsParse: monthsParse,
10764    shortMonthsParse: monthsParse,
10765    weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
10766    weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
10767    weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'),
10768    weekdaysParseExact: true,
10769    longDateFormat: {
10770        LT: 'h:mm A',
10771        LTS: 'h:mm:ss A',
10772        L: 'DD/MM/YYYY',
10773        LL: 'D [de] MMMM [de] YYYY',
10774        LLL: 'D [de] MMMM [de] YYYY h:mm A',
10775        LLLL: 'dddd, D [de] MMMM [de] YYYY h:mm A',
10776    },
10777    calendar: {
10778        sameDay: function () {
10779            return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
10780        },
10781        nextDay: function () {
10782            return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
10783        },
10784        nextWeek: function () {
10785            return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
10786        },
10787        lastDay: function () {
10788            return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
10789        },
10790        lastWeek: function () {
10791            return (
10792                '[el] dddd [pasado a la' +
10793                (this.hours() !== 1 ? 's' : '') +
10794                '] LT'
10795            );
10796        },
10797        sameElse: 'L',
10798    },
10799    relativeTime: {
10800        future: 'en %s',
10801        past: 'hace %s',
10802        s: 'unos segundos',
10803        ss: '%d segundos',
10804        m: 'un minuto',
10805        mm: '%d minutos',
10806        h: 'una hora',
10807        hh: '%d horas',
10808        d: 'un día',
10809        dd: '%d días',
10810        w: 'una semana',
10811        ww: '%d semanas',
10812        M: 'un mes',
10813        MM: '%d meses',
10814        y: 'un año',
10815        yy: '%d años',
10816    },
10817    dayOfMonthOrdinalParse: /\d{1,2}º/,
10818    ordinal: '%dº',
10819    week: {
10820        dow: 1, // Monday is the first day of the week.
10821        doy: 4, // The week that contains Jan 4th is the first week of the year.
10822    },
10823}));
10824
10825
10826/***/ }),
10827/* 48 */
10828/***/ (function(module, __webpack_exports__, __webpack_require__) {
10829
10830"use strict";
10831Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
10832/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
10833//! moment.js locale configuration
10834//! locale : Spanish (Mexico) [es-mx]
10835//! author : JC Franco : https://github.com/jcfranco
10836
10837
10838
10839var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split(
10840        '_'
10841    ),
10842    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'),
10843    monthsParse = [
10844        /^ene/i,
10845        /^feb/i,
10846        /^mar/i,
10847        /^abr/i,
10848        /^may/i,
10849        /^jun/i,
10850        /^jul/i,
10851        /^ago/i,
10852        /^sep/i,
10853        /^oct/i,
10854        /^nov/i,
10855        /^dic/i,
10856    ],
10857    monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;
10858
10859/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('es-mx', {
10860    months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split(
10861        '_'
10862    ),
10863    monthsShort: function (m, format) {
10864        if (!m) {
10865            return monthsShortDot;
10866        } else if (/-MMM-/.test(format)) {
10867            return monthsShort[m.month()];
10868        } else {
10869            return monthsShortDot[m.month()];
10870        }
10871    },
10872    monthsRegex: monthsRegex,
10873    monthsShortRegex: monthsRegex,
10874    monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,
10875    monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,
10876    monthsParse: monthsParse,
10877    longMonthsParse: monthsParse,
10878    shortMonthsParse: monthsParse,
10879    weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
10880    weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
10881    weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'),
10882    weekdaysParseExact: true,
10883    longDateFormat: {
10884        LT: 'H:mm',
10885        LTS: 'H:mm:ss',
10886        L: 'DD/MM/YYYY',
10887        LL: 'D [de] MMMM [de] YYYY',
10888        LLL: 'D [de] MMMM [de] YYYY H:mm',
10889        LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm',
10890    },
10891    calendar: {
10892        sameDay: function () {
10893            return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
10894        },
10895        nextDay: function () {
10896            return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
10897        },
10898        nextWeek: function () {
10899            return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
10900        },
10901        lastDay: function () {
10902            return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
10903        },
10904        lastWeek: function () {
10905            return (
10906                '[el] dddd [pasado a la' +
10907                (this.hours() !== 1 ? 's' : '') +
10908                '] LT'
10909            );
10910        },
10911        sameElse: 'L',
10912    },
10913    relativeTime: {
10914        future: 'en %s',
10915        past: 'hace %s',
10916        s: 'unos segundos',
10917        ss: '%d segundos',
10918        m: 'un minuto',
10919        mm: '%d minutos',
10920        h: 'una hora',
10921        hh: '%d horas',
10922        d: 'un día',
10923        dd: '%d días',
10924        w: 'una semana',
10925        ww: '%d semanas',
10926        M: 'un mes',
10927        MM: '%d meses',
10928        y: 'un año',
10929        yy: '%d años',
10930    },
10931    dayOfMonthOrdinalParse: /\d{1,2}º/,
10932    ordinal: '%dº',
10933    week: {
10934        dow: 0, // Sunday is the first day of the week.
10935        doy: 4, // The week that contains Jan 4th is the first week of the year.
10936    },
10937    invalidDate: 'Fecha inválida',
10938}));
10939
10940
10941/***/ }),
10942/* 49 */
10943/***/ (function(module, __webpack_exports__, __webpack_require__) {
10944
10945"use strict";
10946Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
10947/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
10948//! moment.js locale configuration
10949//! locale : Spanish (United States) [es-us]
10950//! author : bustta : https://github.com/bustta
10951//! author : chrisrodz : https://github.com/chrisrodz
10952
10953
10954
10955var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split(
10956        '_'
10957    ),
10958    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'),
10959    monthsParse = [
10960        /^ene/i,
10961        /^feb/i,
10962        /^mar/i,
10963        /^abr/i,
10964        /^may/i,
10965        /^jun/i,
10966        /^jul/i,
10967        /^ago/i,
10968        /^sep/i,
10969        /^oct/i,
10970        /^nov/i,
10971        /^dic/i,
10972    ],
10973    monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;
10974
10975/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('es-us', {
10976    months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split(
10977        '_'
10978    ),
10979    monthsShort: function (m, format) {
10980        if (!m) {
10981            return monthsShortDot;
10982        } else if (/-MMM-/.test(format)) {
10983            return monthsShort[m.month()];
10984        } else {
10985            return monthsShortDot[m.month()];
10986        }
10987    },
10988    monthsRegex: monthsRegex,
10989    monthsShortRegex: monthsRegex,
10990    monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,
10991    monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,
10992    monthsParse: monthsParse,
10993    longMonthsParse: monthsParse,
10994    shortMonthsParse: monthsParse,
10995    weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
10996    weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
10997    weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'),
10998    weekdaysParseExact: true,
10999    longDateFormat: {
11000        LT: 'h:mm A',
11001        LTS: 'h:mm:ss A',
11002        L: 'MM/DD/YYYY',
11003        LL: 'D [de] MMMM [de] YYYY',
11004        LLL: 'D [de] MMMM [de] YYYY h:mm A',
11005        LLLL: 'dddd, D [de] MMMM [de] YYYY h:mm A',
11006    },
11007    calendar: {
11008        sameDay: function () {
11009            return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
11010        },
11011        nextDay: function () {
11012            return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
11013        },
11014        nextWeek: function () {
11015            return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
11016        },
11017        lastDay: function () {
11018            return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
11019        },
11020        lastWeek: function () {
11021            return (
11022                '[el] dddd [pasado a la' +
11023                (this.hours() !== 1 ? 's' : '') +
11024                '] LT'
11025            );
11026        },
11027        sameElse: 'L',
11028    },
11029    relativeTime: {
11030        future: 'en %s',
11031        past: 'hace %s',
11032        s: 'unos segundos',
11033        ss: '%d segundos',
11034        m: 'un minuto',
11035        mm: '%d minutos',
11036        h: 'una hora',
11037        hh: '%d horas',
11038        d: 'un día',
11039        dd: '%d días',
11040        w: 'una semana',
11041        ww: '%d semanas',
11042        M: 'un mes',
11043        MM: '%d meses',
11044        y: 'un año',
11045        yy: '%d años',
11046    },
11047    dayOfMonthOrdinalParse: /\d{1,2}º/,
11048    ordinal: '%dº',
11049    week: {
11050        dow: 0, // Sunday is the first day of the week.
11051        doy: 6, // The week that contains Jan 6th is the first week of the year.
11052    },
11053}));
11054
11055
11056/***/ }),
11057/* 50 */
11058/***/ (function(module, __webpack_exports__, __webpack_require__) {
11059
11060"use strict";
11061Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
11062/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
11063//! moment.js locale configuration
11064//! locale : Estonian [et]
11065//! author : Henry Kehlmann : https://github.com/madhenry
11066//! improvements : Illimar Tambek : https://github.com/ragulka
11067
11068
11069
11070function processRelativeTime(number, withoutSuffix, key, isFuture) {
11071    var format = {
11072        s: ['mõne sekundi', 'mõni sekund', 'paar sekundit'],
11073        ss: [number + 'sekundi', number + 'sekundit'],
11074        m: ['ühe minuti', 'üks minut'],
11075        mm: [number + ' minuti', number + ' minutit'],
11076        h: ['ühe tunni', 'tund aega', 'üks tund'],
11077        hh: [number + ' tunni', number + ' tundi'],
11078        d: ['ühe päeva', 'üks päev'],
11079        M: ['kuu aja', 'kuu aega', 'üks kuu'],
11080        MM: [number + ' kuu', number + ' kuud'],
11081        y: ['ühe aasta', 'aasta', 'üks aasta'],
11082        yy: [number + ' aasta', number + ' aastat'],
11083    };
11084    if (withoutSuffix) {
11085        return format[key][2] ? format[key][2] : format[key][1];
11086    }
11087    return isFuture ? format[key][0] : format[key][1];
11088}
11089
11090/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('et', {
11091    months: 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split(
11092        '_'
11093    ),
11094    monthsShort: 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split(
11095        '_'
11096    ),
11097    weekdays: 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split(
11098        '_'
11099    ),
11100    weekdaysShort: 'P_E_T_K_N_R_L'.split('_'),
11101    weekdaysMin: 'P_E_T_K_N_R_L'.split('_'),
11102    longDateFormat: {
11103        LT: 'H:mm',
11104        LTS: 'H:mm:ss',
11105        L: 'DD.MM.YYYY',
11106        LL: 'D. MMMM YYYY',
11107        LLL: 'D. MMMM YYYY H:mm',
11108        LLLL: 'dddd, D. MMMM YYYY H:mm',
11109    },
11110    calendar: {
11111        sameDay: '[Täna,] LT',
11112        nextDay: '[Homme,] LT',
11113        nextWeek: '[Järgmine] dddd LT',
11114        lastDay: '[Eile,] LT',
11115        lastWeek: '[Eelmine] dddd LT',
11116        sameElse: 'L',
11117    },
11118    relativeTime: {
11119        future: '%s pärast',
11120        past: '%s tagasi',
11121        s: processRelativeTime,
11122        ss: processRelativeTime,
11123        m: processRelativeTime,
11124        mm: processRelativeTime,
11125        h: processRelativeTime,
11126        hh: processRelativeTime,
11127        d: processRelativeTime,
11128        dd: '%d päeva',
11129        M: processRelativeTime,
11130        MM: processRelativeTime,
11131        y: processRelativeTime,
11132        yy: processRelativeTime,
11133    },
11134    dayOfMonthOrdinalParse: /\d{1,2}\./,
11135    ordinal: '%d.',
11136    week: {
11137        dow: 1, // Monday is the first day of the week.
11138        doy: 4, // The week that contains Jan 4th is the first week of the year.
11139    },
11140}));
11141
11142
11143/***/ }),
11144/* 51 */
11145/***/ (function(module, __webpack_exports__, __webpack_require__) {
11146
11147"use strict";
11148Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
11149/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
11150//! moment.js locale configuration
11151//! locale : Basque [eu]
11152//! author : Eneko Illarramendi : https://github.com/eillarra
11153
11154
11155
11156/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('eu', {
11157    months: 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split(
11158        '_'
11159    ),
11160    monthsShort: 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split(
11161        '_'
11162    ),
11163    monthsParseExact: true,
11164    weekdays: 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split(
11165        '_'
11166    ),
11167    weekdaysShort: 'ig._al._ar._az._og._ol._lr.'.split('_'),
11168    weekdaysMin: 'ig_al_ar_az_og_ol_lr'.split('_'),
11169    weekdaysParseExact: true,
11170    longDateFormat: {
11171        LT: 'HH:mm',
11172        LTS: 'HH:mm:ss',
11173        L: 'YYYY-MM-DD',
11174        LL: 'YYYY[ko] MMMM[ren] D[a]',
11175        LLL: 'YYYY[ko] MMMM[ren] D[a] HH:mm',
11176        LLLL: 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',
11177        l: 'YYYY-M-D',
11178        ll: 'YYYY[ko] MMM D[a]',
11179        lll: 'YYYY[ko] MMM D[a] HH:mm',
11180        llll: 'ddd, YYYY[ko] MMM D[a] HH:mm',
11181    },
11182    calendar: {
11183        sameDay: '[gaur] LT[etan]',
11184        nextDay: '[bihar] LT[etan]',
11185        nextWeek: 'dddd LT[etan]',
11186        lastDay: '[atzo] LT[etan]',
11187        lastWeek: '[aurreko] dddd LT[etan]',
11188        sameElse: 'L',
11189    },
11190    relativeTime: {
11191        future: '%s barru',
11192        past: 'duela %s',
11193        s: 'segundo batzuk',
11194        ss: '%d segundo',
11195        m: 'minutu bat',
11196        mm: '%d minutu',
11197        h: 'ordu bat',
11198        hh: '%d ordu',
11199        d: 'egun bat',
11200        dd: '%d egun',
11201        M: 'hilabete bat',
11202        MM: '%d hilabete',
11203        y: 'urte bat',
11204        yy: '%d urte',
11205    },
11206    dayOfMonthOrdinalParse: /\d{1,2}\./,
11207    ordinal: '%d.',
11208    week: {
11209        dow: 1, // Monday is the first day of the week.
11210        doy: 7, // The week that contains Jan 7th is the first week of the year.
11211    },
11212}));
11213
11214
11215/***/ }),
11216/* 52 */
11217/***/ (function(module, __webpack_exports__, __webpack_require__) {
11218
11219"use strict";
11220Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
11221/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
11222//! moment.js locale configuration
11223//! locale : Persian [fa]
11224//! author : Ebrahim Byagowi : https://github.com/ebraminio
11225
11226
11227
11228var symbolMap = {
11229        1: 'Û±',
11230        2: 'Û²',
11231        3: 'Û³',
11232        4: 'Û´',
11233        5: 'Ûµ',
11234        6: 'Û¶',
11235        7: 'Û·',
11236        8: 'Û¸',
11237        9: 'Û¹',
11238        0: 'Û°',
11239    },
11240    numberMap = {
11241        'Û±': '1',
11242        'Û²': '2',
11243        'Û³': '3',
11244        'Û´': '4',
11245        'Ûµ': '5',
11246        'Û¶': '6',
11247        'Û·': '7',
11248        'Û¸': '8',
11249        'Û¹': '9',
11250        'Û°': '0',
11251    };
11252
11253/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('fa', {
11254    months: 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split(
11255        '_'
11256    ),
11257    monthsShort: 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split(
11258        '_'
11259    ),
11260    weekdays: 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split(
11261        '_'
11262    ),
11263    weekdaysShort: 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split(
11264        '_'
11265    ),
11266    weekdaysMin: 'ی_د_س_چ_پ_ج_ش'.split('_'),
11267    weekdaysParseExact: true,
11268    longDateFormat: {
11269        LT: 'HH:mm',
11270        LTS: 'HH:mm:ss',
11271        L: 'DD/MM/YYYY',
11272        LL: 'D MMMM YYYY',
11273        LLL: 'D MMMM YYYY HH:mm',
11274        LLLL: 'dddd, D MMMM YYYY HH:mm',
11275    },
11276    meridiemParse: /قبل از ظهر|بعد از ظهر/,
11277    isPM: function (input) {
11278        return /بعد از ظهر/.test(input);
11279    },
11280    meridiem: function (hour, minute, isLower) {
11281        if (hour < 12) {
11282            return 'قبل از ظهر';
11283        } else {
11284            return 'بعد از ظهر';
11285        }
11286    },
11287    calendar: {
11288        sameDay: '[امروز ساعت] LT',
11289        nextDay: '[فردا ساعت] LT',
11290        nextWeek: 'dddd [ساعت] LT',
11291        lastDay: '[دیروز ساعت] LT',
11292        lastWeek: 'dddd [پیش] [ساعت] LT',
11293        sameElse: 'L',
11294    },
11295    relativeTime: {
11296        future: 'در %s',
11297        past: '%s پیش',
11298        s: 'چند ثانیه',
11299        ss: '%d ثانیه',
11300        m: 'یک دقیقه',
11301        mm: '%d دقیقه',
11302        h: 'یک ساعت',
11303        hh: '%d ساعت',
11304        d: 'یک روز',
11305        dd: '%d روز',
11306        M: 'یک ماه',
11307        MM: '%d ماه',
11308        y: 'یک سال',
11309        yy: '%d سال',
11310    },
11311    preparse: function (string) {
11312        return string
11313            .replace(/[Û°-Û¹]/g, function (match) {
11314                return numberMap[match];
11315            })
11316            .replace(/،/g, ',');
11317    },
11318    postformat: function (string) {
11319        return string
11320            .replace(/\d/g, function (match) {
11321                return symbolMap[match];
11322            })
11323            .replace(/,/g, '،');
11324    },
11325    dayOfMonthOrdinalParse: /\d{1,2}م/,
11326    ordinal: '%dم',
11327    week: {
11328        dow: 6, // Saturday is the first day of the week.
11329        doy: 12, // The week that contains Jan 12th is the first week of the year.
11330    },
11331}));
11332
11333
11334/***/ }),
11335/* 53 */
11336/***/ (function(module, __webpack_exports__, __webpack_require__) {
11337
11338"use strict";
11339Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
11340/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
11341//! moment.js locale configuration
11342//! locale : Finnish [fi]
11343//! author : Tarmo Aidantausta : https://github.com/bleadof
11344
11345
11346
11347var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(
11348        ' '
11349    ),
11350    numbersFuture = [
11351        'nolla',
11352        'yhden',
11353        'kahden',
11354        'kolmen',
11355        'neljän',
11356        'viiden',
11357        'kuuden',
11358        numbersPast[7],
11359        numbersPast[8],
11360        numbersPast[9],
11361    ];
11362function translate(number, withoutSuffix, key, isFuture) {
11363    var result = '';
11364    switch (key) {
11365        case 's':
11366            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';
11367        case 'ss':
11368            result = isFuture ? 'sekunnin' : 'sekuntia';
11369            break;
11370        case 'm':
11371            return isFuture ? 'minuutin' : 'minuutti';
11372        case 'mm':
11373            result = isFuture ? 'minuutin' : 'minuuttia';
11374            break;
11375        case 'h':
11376            return isFuture ? 'tunnin' : 'tunti';
11377        case 'hh':
11378            result = isFuture ? 'tunnin' : 'tuntia';
11379            break;
11380        case 'd':
11381            return isFuture ? 'päivän' : 'päivä';
11382        case 'dd':
11383            result = isFuture ? 'päivän' : 'päivää';
11384            break;
11385        case 'M':
11386            return isFuture ? 'kuukauden' : 'kuukausi';
11387        case 'MM':
11388            result = isFuture ? 'kuukauden' : 'kuukautta';
11389            break;
11390        case 'y':
11391            return isFuture ? 'vuoden' : 'vuosi';
11392        case 'yy':
11393            result = isFuture ? 'vuoden' : 'vuotta';
11394            break;
11395    }
11396    result = verbalNumber(number, isFuture) + ' ' + result;
11397    return result;
11398}
11399function verbalNumber(number, isFuture) {
11400    return number < 10
11401        ? isFuture
11402            ? numbersFuture[number]
11403            : numbersPast[number]
11404        : number;
11405}
11406
11407/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('fi', {
11408    months: 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split(
11409        '_'
11410    ),
11411    monthsShort: 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split(
11412        '_'
11413    ),
11414    weekdays: 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split(
11415        '_'
11416    ),
11417    weekdaysShort: 'su_ma_ti_ke_to_pe_la'.split('_'),
11418    weekdaysMin: 'su_ma_ti_ke_to_pe_la'.split('_'),
11419    longDateFormat: {
11420        LT: 'HH.mm',
11421        LTS: 'HH.mm.ss',
11422        L: 'DD.MM.YYYY',
11423        LL: 'Do MMMM[ta] YYYY',
11424        LLL: 'Do MMMM[ta] YYYY, [klo] HH.mm',
11425        LLLL: 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',
11426        l: 'D.M.YYYY',
11427        ll: 'Do MMM YYYY',
11428        lll: 'Do MMM YYYY, [klo] HH.mm',
11429        llll: 'ddd, Do MMM YYYY, [klo] HH.mm',
11430    },
11431    calendar: {
11432        sameDay: '[tänään] [klo] LT',
11433        nextDay: '[huomenna] [klo] LT',
11434        nextWeek: 'dddd [klo] LT',
11435        lastDay: '[eilen] [klo] LT',
11436        lastWeek: '[viime] dddd[na] [klo] LT',
11437        sameElse: 'L',
11438    },
11439    relativeTime: {
11440        future: '%s päästä',
11441        past: '%s sitten',
11442        s: translate,
11443        ss: translate,
11444        m: translate,
11445        mm: translate,
11446        h: translate,
11447        hh: translate,
11448        d: translate,
11449        dd: translate,
11450        M: translate,
11451        MM: translate,
11452        y: translate,
11453        yy: translate,
11454    },
11455    dayOfMonthOrdinalParse: /\d{1,2}\./,
11456    ordinal: '%d.',
11457    week: {
11458        dow: 1, // Monday is the first day of the week.
11459        doy: 4, // The week that contains Jan 4th is the first week of the year.
11460    },
11461}));
11462
11463
11464/***/ }),
11465/* 54 */
11466/***/ (function(module, __webpack_exports__, __webpack_require__) {
11467
11468"use strict";
11469Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
11470/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
11471//! moment.js locale configuration
11472//! locale : Filipino [fil]
11473//! author : Dan Hagman : https://github.com/hagmandan
11474//! author : Matthew Co : https://github.com/matthewdeeco
11475
11476
11477
11478/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('fil', {
11479    months: 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split(
11480        '_'
11481    ),
11482    monthsShort: 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),
11483    weekdays: 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split(
11484        '_'
11485    ),
11486    weekdaysShort: 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),
11487    weekdaysMin: 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),
11488    longDateFormat: {
11489        LT: 'HH:mm',
11490        LTS: 'HH:mm:ss',
11491        L: 'MM/D/YYYY',
11492        LL: 'MMMM D, YYYY',
11493        LLL: 'MMMM D, YYYY HH:mm',
11494        LLLL: 'dddd, MMMM DD, YYYY HH:mm',
11495    },
11496    calendar: {
11497        sameDay: 'LT [ngayong araw]',
11498        nextDay: '[Bukas ng] LT',
11499        nextWeek: 'LT [sa susunod na] dddd',
11500        lastDay: 'LT [kahapon]',
11501        lastWeek: 'LT [noong nakaraang] dddd',
11502        sameElse: 'L',
11503    },
11504    relativeTime: {
11505        future: 'sa loob ng %s',
11506        past: '%s ang nakalipas',
11507        s: 'ilang segundo',
11508        ss: '%d segundo',
11509        m: 'isang minuto',
11510        mm: '%d minuto',
11511        h: 'isang oras',
11512        hh: '%d oras',
11513        d: 'isang araw',
11514        dd: '%d araw',
11515        M: 'isang buwan',
11516        MM: '%d buwan',
11517        y: 'isang taon',
11518        yy: '%d taon',
11519    },
11520    dayOfMonthOrdinalParse: /\d{1,2}/,
11521    ordinal: function (number) {
11522        return number;
11523    },
11524    week: {
11525        dow: 1, // Monday is the first day of the week.
11526        doy: 4, // The week that contains Jan 4th is the first week of the year.
11527    },
11528}));
11529
11530
11531/***/ }),
11532/* 55 */
11533/***/ (function(module, __webpack_exports__, __webpack_require__) {
11534
11535"use strict";
11536Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
11537/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
11538//! moment.js locale configuration
11539//! locale : Faroese [fo]
11540//! author : Ragnar Johannesen : https://github.com/ragnar123
11541//! author : Kristian Sakarisson : https://github.com/sakarisson
11542
11543
11544
11545/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('fo', {
11546    months: 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split(
11547        '_'
11548    ),
11549    monthsShort: 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),
11550    weekdays: 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split(
11551        '_'
11552    ),
11553    weekdaysShort: 'sun_mán_týs_mik_hós_frí_ley'.split('_'),
11554    weekdaysMin: 'su_má_tý_mi_hó_fr_le'.split('_'),
11555    longDateFormat: {
11556        LT: 'HH:mm',
11557        LTS: 'HH:mm:ss',
11558        L: 'DD/MM/YYYY',
11559        LL: 'D MMMM YYYY',
11560        LLL: 'D MMMM YYYY HH:mm',
11561        LLLL: 'dddd D. MMMM, YYYY HH:mm',
11562    },
11563    calendar: {
11564        sameDay: '[Í dag kl.] LT',
11565        nextDay: '[Í morgin kl.] LT',
11566        nextWeek: 'dddd [kl.] LT',
11567        lastDay: '[Í gjár kl.] LT',
11568        lastWeek: '[síðstu] dddd [kl] LT',
11569        sameElse: 'L',
11570    },
11571    relativeTime: {
11572        future: 'um %s',
11573        past: '%s síðani',
11574        s: 'fá sekund',
11575        ss: '%d sekundir',
11576        m: 'ein minuttur',
11577        mm: '%d minuttir',
11578        h: 'ein tími',
11579        hh: '%d tímar',
11580        d: 'ein dagur',
11581        dd: '%d dagar',
11582        M: 'ein mánaður',
11583        MM: '%d mánaðir',
11584        y: 'eitt ár',
11585        yy: '%d ár',
11586    },
11587    dayOfMonthOrdinalParse: /\d{1,2}\./,
11588    ordinal: '%d.',
11589    week: {
11590        dow: 1, // Monday is the first day of the week.
11591        doy: 4, // The week that contains Jan 4th is the first week of the year.
11592    },
11593}));
11594
11595
11596/***/ }),
11597/* 56 */
11598/***/ (function(module, __webpack_exports__, __webpack_require__) {
11599
11600"use strict";
11601Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
11602/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
11603//! moment.js locale configuration
11604//! locale : French [fr]
11605//! author : John Fischer : https://github.com/jfroffice
11606
11607
11608
11609var monthsStrictRegex = /^(janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,
11610    monthsShortStrictRegex = /(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?)/i,
11611    monthsRegex = /(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?|janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,
11612    monthsParse = [
11613        /^janv/i,
11614        /^févr/i,
11615        /^mars/i,
11616        /^avr/i,
11617        /^mai/i,
11618        /^juin/i,
11619        /^juil/i,
11620        /^août/i,
11621        /^sept/i,
11622        /^oct/i,
11623        /^nov/i,
11624        /^déc/i,
11625    ];
11626
11627/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('fr', {
11628    months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split(
11629        '_'
11630    ),
11631    monthsShort: 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split(
11632        '_'
11633    ),
11634    monthsRegex: monthsRegex,
11635    monthsShortRegex: monthsRegex,
11636    monthsStrictRegex: monthsStrictRegex,
11637    monthsShortStrictRegex: monthsShortStrictRegex,
11638    monthsParse: monthsParse,
11639    longMonthsParse: monthsParse,
11640    shortMonthsParse: monthsParse,
11641    weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
11642    weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
11643    weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'),
11644    weekdaysParseExact: true,
11645    longDateFormat: {
11646        LT: 'HH:mm',
11647        LTS: 'HH:mm:ss',
11648        L: 'DD/MM/YYYY',
11649        LL: 'D MMMM YYYY',
11650        LLL: 'D MMMM YYYY HH:mm',
11651        LLLL: 'dddd D MMMM YYYY HH:mm',
11652    },
11653    calendar: {
11654        sameDay: '[Aujourd’hui à] LT',
11655        nextDay: '[Demain à] LT',
11656        nextWeek: 'dddd [à] LT',
11657        lastDay: '[Hier à] LT',
11658        lastWeek: 'dddd [dernier à] LT',
11659        sameElse: 'L',
11660    },
11661    relativeTime: {
11662        future: 'dans %s',
11663        past: 'il y a %s',
11664        s: 'quelques secondes',
11665        ss: '%d secondes',
11666        m: 'une minute',
11667        mm: '%d minutes',
11668        h: 'une heure',
11669        hh: '%d heures',
11670        d: 'un jour',
11671        dd: '%d jours',
11672        w: 'une semaine',
11673        ww: '%d semaines',
11674        M: 'un mois',
11675        MM: '%d mois',
11676        y: 'un an',
11677        yy: '%d ans',
11678    },
11679    dayOfMonthOrdinalParse: /\d{1,2}(er|)/,
11680    ordinal: function (number, period) {
11681        switch (period) {
11682            // TODO: Return 'e' when day of month > 1. Move this case inside
11683            // block for masculine words below.
11684            // See https://github.com/moment/moment/issues/3375
11685            case 'D':
11686                return number + (number === 1 ? 'er' : '');
11687
11688            // Words with masculine grammatical gender: mois, trimestre, jour
11689            default:
11690            case 'M':
11691            case 'Q':
11692            case 'DDD':
11693            case 'd':
11694                return number + (number === 1 ? 'er' : 'e');
11695
11696            // Words with feminine grammatical gender: semaine
11697            case 'w':
11698            case 'W':
11699                return number + (number === 1 ? 're' : 'e');
11700        }
11701    },
11702    week: {
11703        dow: 1, // Monday is the first day of the week.
11704        doy: 4, // The week that contains Jan 4th is the first week of the year.
11705    },
11706}));
11707
11708
11709/***/ }),
11710/* 57 */
11711/***/ (function(module, __webpack_exports__, __webpack_require__) {
11712
11713"use strict";
11714Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
11715/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
11716//! moment.js locale configuration
11717//! locale : French (Canada) [fr-ca]
11718//! author : Jonathan Abourbih : https://github.com/jonbca
11719
11720
11721
11722/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('fr-ca', {
11723    months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split(
11724        '_'
11725    ),
11726    monthsShort: 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split(
11727        '_'
11728    ),
11729    monthsParseExact: true,
11730    weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
11731    weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
11732    weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'),
11733    weekdaysParseExact: true,
11734    longDateFormat: {
11735        LT: 'HH:mm',
11736        LTS: 'HH:mm:ss',
11737        L: 'YYYY-MM-DD',
11738        LL: 'D MMMM YYYY',
11739        LLL: 'D MMMM YYYY HH:mm',
11740        LLLL: 'dddd D MMMM YYYY HH:mm',
11741    },
11742    calendar: {
11743        sameDay: '[Aujourd’hui à] LT',
11744        nextDay: '[Demain à] LT',
11745        nextWeek: 'dddd [à] LT',
11746        lastDay: '[Hier à] LT',
11747        lastWeek: 'dddd [dernier à] LT',
11748        sameElse: 'L',
11749    },
11750    relativeTime: {
11751        future: 'dans %s',
11752        past: 'il y a %s',
11753        s: 'quelques secondes',
11754        ss: '%d secondes',
11755        m: 'une minute',
11756        mm: '%d minutes',
11757        h: 'une heure',
11758        hh: '%d heures',
11759        d: 'un jour',
11760        dd: '%d jours',
11761        M: 'un mois',
11762        MM: '%d mois',
11763        y: 'un an',
11764        yy: '%d ans',
11765    },
11766    dayOfMonthOrdinalParse: /\d{1,2}(er|e)/,
11767    ordinal: function (number, period) {
11768        switch (period) {
11769            // Words with masculine grammatical gender: mois, trimestre, jour
11770            default:
11771            case 'M':
11772            case 'Q':
11773            case 'D':
11774            case 'DDD':
11775            case 'd':
11776                return number + (number === 1 ? 'er' : 'e');
11777
11778            // Words with feminine grammatical gender: semaine
11779            case 'w':
11780            case 'W':
11781                return number + (number === 1 ? 're' : 'e');
11782        }
11783    },
11784}));
11785
11786
11787/***/ }),
11788/* 58 */
11789/***/ (function(module, __webpack_exports__, __webpack_require__) {
11790
11791"use strict";
11792Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
11793/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
11794//! moment.js locale configuration
11795//! locale : French (Switzerland) [fr-ch]
11796//! author : Gaspard Bucher : https://github.com/gaspard
11797
11798
11799
11800/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('fr-ch', {
11801    months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split(
11802        '_'
11803    ),
11804    monthsShort: 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split(
11805        '_'
11806    ),
11807    monthsParseExact: true,
11808    weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
11809    weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
11810    weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'),
11811    weekdaysParseExact: true,
11812    longDateFormat: {
11813        LT: 'HH:mm',
11814        LTS: 'HH:mm:ss',
11815        L: 'DD.MM.YYYY',
11816        LL: 'D MMMM YYYY',
11817        LLL: 'D MMMM YYYY HH:mm',
11818        LLLL: 'dddd D MMMM YYYY HH:mm',
11819    },
11820    calendar: {
11821        sameDay: '[Aujourd’hui à] LT',
11822        nextDay: '[Demain à] LT',
11823        nextWeek: 'dddd [à] LT',
11824        lastDay: '[Hier à] LT',
11825        lastWeek: 'dddd [dernier à] LT',
11826        sameElse: 'L',
11827    },
11828    relativeTime: {
11829        future: 'dans %s',
11830        past: 'il y a %s',
11831        s: 'quelques secondes',
11832        ss: '%d secondes',
11833        m: 'une minute',
11834        mm: '%d minutes',
11835        h: 'une heure',
11836        hh: '%d heures',
11837        d: 'un jour',
11838        dd: '%d jours',
11839        M: 'un mois',
11840        MM: '%d mois',
11841        y: 'un an',
11842        yy: '%d ans',
11843    },
11844    dayOfMonthOrdinalParse: /\d{1,2}(er|e)/,
11845    ordinal: function (number, period) {
11846        switch (period) {
11847            // Words with masculine grammatical gender: mois, trimestre, jour
11848            default:
11849            case 'M':
11850            case 'Q':
11851            case 'D':
11852            case 'DDD':
11853            case 'd':
11854                return number + (number === 1 ? 'er' : 'e');
11855
11856            // Words with feminine grammatical gender: semaine
11857            case 'w':
11858            case 'W':
11859                return number + (number === 1 ? 're' : 'e');
11860        }
11861    },
11862    week: {
11863        dow: 1, // Monday is the first day of the week.
11864        doy: 4, // The week that contains Jan 4th is the first week of the year.
11865    },
11866}));
11867
11868
11869/***/ }),
11870/* 59 */
11871/***/ (function(module, __webpack_exports__, __webpack_require__) {
11872
11873"use strict";
11874Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
11875/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
11876//! moment.js locale configuration
11877//! locale : Frisian [fy]
11878//! author : Robin van der Vliet : https://github.com/robin0van0der0v
11879
11880
11881
11882var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split(
11883        '_'
11884    ),
11885    monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split(
11886        '_'
11887    );
11888
11889/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('fy', {
11890    months: 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split(
11891        '_'
11892    ),
11893    monthsShort: function (m, format) {
11894        if (!m) {
11895            return monthsShortWithDots;
11896        } else if (/-MMM-/.test(format)) {
11897            return monthsShortWithoutDots[m.month()];
11898        } else {
11899            return monthsShortWithDots[m.month()];
11900        }
11901    },
11902    monthsParseExact: true,
11903    weekdays: 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split(
11904        '_'
11905    ),
11906    weekdaysShort: 'si._mo._ti._wo._to._fr._so.'.split('_'),
11907    weekdaysMin: 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),
11908    weekdaysParseExact: true,
11909    longDateFormat: {
11910        LT: 'HH:mm',
11911        LTS: 'HH:mm:ss',
11912        L: 'DD-MM-YYYY',
11913        LL: 'D MMMM YYYY',
11914        LLL: 'D MMMM YYYY HH:mm',
11915        LLLL: 'dddd D MMMM YYYY HH:mm',
11916    },
11917    calendar: {
11918        sameDay: '[hjoed om] LT',
11919        nextDay: '[moarn om] LT',
11920        nextWeek: 'dddd [om] LT',
11921        lastDay: '[juster om] LT',
11922        lastWeek: '[ôfrûne] dddd [om] LT',
11923        sameElse: 'L',
11924    },
11925    relativeTime: {
11926        future: 'oer %s',
11927        past: '%s lyn',
11928        s: 'in pear sekonden',
11929        ss: '%d sekonden',
11930        m: 'ien minút',
11931        mm: '%d minuten',
11932        h: 'ien oere',
11933        hh: '%d oeren',
11934        d: 'ien dei',
11935        dd: '%d dagen',
11936        M: 'ien moanne',
11937        MM: '%d moannen',
11938        y: 'ien jier',
11939        yy: '%d jierren',
11940    },
11941    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
11942    ordinal: function (number) {
11943        return (
11944            number +
11945            (number === 1 || number === 8 || number >= 20 ? 'ste' : 'de')
11946        );
11947    },
11948    week: {
11949        dow: 1, // Monday is the first day of the week.
11950        doy: 4, // The week that contains Jan 4th is the first week of the year.
11951    },
11952}));
11953
11954
11955/***/ }),
11956/* 60 */
11957/***/ (function(module, __webpack_exports__, __webpack_require__) {
11958
11959"use strict";
11960Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
11961/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
11962//! moment.js locale configuration
11963//! locale : Irish or Irish Gaelic [ga]
11964//! author : André Silva : https://github.com/askpt
11965
11966
11967
11968var months = [
11969        'Eanáir',
11970        'Feabhra',
11971        'Márta',
11972        'Aibreán',
11973        'Bealtaine',
11974        'Meitheamh',
11975        'Iúil',
11976        'Lúnasa',
11977        'Meán Fómhair',
11978        'Deireadh Fómhair',
11979        'Samhain',
11980        'Nollaig',
11981    ],
11982    monthsShort = [
11983        'Ean',
11984        'Feabh',
11985        'Márt',
11986        'Aib',
11987        'Beal',
11988        'Meith',
11989        'Iúil',
11990        'Lún',
11991        'M.F.',
11992        'D.F.',
11993        'Samh',
11994        'Noll',
11995    ],
11996    weekdays = [
11997        'Dé Domhnaigh',
11998        'Dé Luain',
11999        'Dé Máirt',
12000        'Dé Céadaoin',
12001        'Déardaoin',
12002        'Dé hAoine',
12003        'Dé Sathairn',
12004    ],
12005    weekdaysShort = ['Domh', 'Luan', 'Máirt', 'Céad', 'Déar', 'Aoine', 'Sath'],
12006    weekdaysMin = ['Do', 'Lu', 'Má', 'Cé', 'Dé', 'A', 'Sa'];
12007
12008/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ga', {
12009    months: months,
12010    monthsShort: monthsShort,
12011    monthsParseExact: true,
12012    weekdays: weekdays,
12013    weekdaysShort: weekdaysShort,
12014    weekdaysMin: weekdaysMin,
12015    longDateFormat: {
12016        LT: 'HH:mm',
12017        LTS: 'HH:mm:ss',
12018        L: 'DD/MM/YYYY',
12019        LL: 'D MMMM YYYY',
12020        LLL: 'D MMMM YYYY HH:mm',
12021        LLLL: 'dddd, D MMMM YYYY HH:mm',
12022    },
12023    calendar: {
12024        sameDay: '[Inniu ag] LT',
12025        nextDay: '[Amárach ag] LT',
12026        nextWeek: 'dddd [ag] LT',
12027        lastDay: '[Inné ag] LT',
12028        lastWeek: 'dddd [seo caite] [ag] LT',
12029        sameElse: 'L',
12030    },
12031    relativeTime: {
12032        future: 'i %s',
12033        past: '%s ó shin',
12034        s: 'cúpla soicind',
12035        ss: '%d soicind',
12036        m: 'nóiméad',
12037        mm: '%d nóiméad',
12038        h: 'uair an chloig',
12039        hh: '%d uair an chloig',
12040        d: 'lá',
12041        dd: '%d lá',
12042        M: 'mí',
12043        MM: '%d míonna',
12044        y: 'bliain',
12045        yy: '%d bliain',
12046    },
12047    dayOfMonthOrdinalParse: /\d{1,2}(d|na|mh)/,
12048    ordinal: function (number) {
12049        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';
12050        return number + output;
12051    },
12052    week: {
12053        dow: 1, // Monday is the first day of the week.
12054        doy: 4, // The week that contains Jan 4th is the first week of the year.
12055    },
12056}));
12057
12058
12059/***/ }),
12060/* 61 */
12061/***/ (function(module, __webpack_exports__, __webpack_require__) {
12062
12063"use strict";
12064Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
12065/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
12066//! moment.js locale configuration
12067//! locale : Scottish Gaelic [gd]
12068//! author : Jon Ashdown : https://github.com/jonashdown
12069
12070
12071
12072var months = [
12073        'Am Faoilleach',
12074        'An Gearran',
12075        'Am Màrt',
12076        'An Giblean',
12077        'An Cèitean',
12078        'An t-Ògmhios',
12079        'An t-Iuchar',
12080        'An Lùnastal',
12081        'An t-Sultain',
12082        'An Dàmhair',
12083        'An t-Samhain',
12084        'An Dùbhlachd',
12085    ],
12086    monthsShort = [
12087        'Faoi',
12088        'Gear',
12089        'Màrt',
12090        'Gibl',
12091        'Cèit',
12092        'Ògmh',
12093        'Iuch',
12094        'Lùn',
12095        'Sult',
12096        'Dàmh',
12097        'Samh',
12098        'Dùbh',
12099    ],
12100    weekdays = [
12101        'Didòmhnaich',
12102        'Diluain',
12103        'Dimàirt',
12104        'Diciadain',
12105        'Diardaoin',
12106        'Dihaoine',
12107        'Disathairne',
12108    ],
12109    weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis'],
12110    weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa'];
12111
12112/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('gd', {
12113    months: months,
12114    monthsShort: monthsShort,
12115    monthsParseExact: true,
12116    weekdays: weekdays,
12117    weekdaysShort: weekdaysShort,
12118    weekdaysMin: weekdaysMin,
12119    longDateFormat: {
12120        LT: 'HH:mm',
12121        LTS: 'HH:mm:ss',
12122        L: 'DD/MM/YYYY',
12123        LL: 'D MMMM YYYY',
12124        LLL: 'D MMMM YYYY HH:mm',
12125        LLLL: 'dddd, D MMMM YYYY HH:mm',
12126    },
12127    calendar: {
12128        sameDay: '[An-diugh aig] LT',
12129        nextDay: '[A-màireach aig] LT',
12130        nextWeek: 'dddd [aig] LT',
12131        lastDay: '[An-dè aig] LT',
12132        lastWeek: 'dddd [seo chaidh] [aig] LT',
12133        sameElse: 'L',
12134    },
12135    relativeTime: {
12136        future: 'ann an %s',
12137        past: 'bho chionn %s',
12138        s: 'beagan diogan',
12139        ss: '%d diogan',
12140        m: 'mionaid',
12141        mm: '%d mionaidean',
12142        h: 'uair',
12143        hh: '%d uairean',
12144        d: 'latha',
12145        dd: '%d latha',
12146        M: 'mìos',
12147        MM: '%d mìosan',
12148        y: 'bliadhna',
12149        yy: '%d bliadhna',
12150    },
12151    dayOfMonthOrdinalParse: /\d{1,2}(d|na|mh)/,
12152    ordinal: function (number) {
12153        var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh';
12154        return number + output;
12155    },
12156    week: {
12157        dow: 1, // Monday is the first day of the week.
12158        doy: 4, // The week that contains Jan 4th is the first week of the year.
12159    },
12160}));
12161
12162
12163/***/ }),
12164/* 62 */
12165/***/ (function(module, __webpack_exports__, __webpack_require__) {
12166
12167"use strict";
12168Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
12169/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
12170//! moment.js locale configuration
12171//! locale : Galician [gl]
12172//! author : Juan G. Hurtado : https://github.com/juanghurtado
12173
12174
12175
12176/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('gl', {
12177    months: 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split(
12178        '_'
12179    ),
12180    monthsShort: 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split(
12181        '_'
12182    ),
12183    monthsParseExact: true,
12184    weekdays: 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'),
12185    weekdaysShort: 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'),
12186    weekdaysMin: 'do_lu_ma_mé_xo_ve_sá'.split('_'),
12187    weekdaysParseExact: true,
12188    longDateFormat: {
12189        LT: 'H:mm',
12190        LTS: 'H:mm:ss',
12191        L: 'DD/MM/YYYY',
12192        LL: 'D [de] MMMM [de] YYYY',
12193        LLL: 'D [de] MMMM [de] YYYY H:mm',
12194        LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm',
12195    },
12196    calendar: {
12197        sameDay: function () {
12198            return '[hoxe ' + (this.hours() !== 1 ? 'ás' : 'á') + '] LT';
12199        },
12200        nextDay: function () {
12201            return '[mañá ' + (this.hours() !== 1 ? 'ás' : 'á') + '] LT';
12202        },
12203        nextWeek: function () {
12204            return 'dddd [' + (this.hours() !== 1 ? 'ás' : 'a') + '] LT';
12205        },
12206        lastDay: function () {
12207            return '[onte ' + (this.hours() !== 1 ? 'á' : 'a') + '] LT';
12208        },
12209        lastWeek: function () {
12210            return (
12211                '[o] dddd [pasado ' + (this.hours() !== 1 ? 'ás' : 'a') + '] LT'
12212            );
12213        },
12214        sameElse: 'L',
12215    },
12216    relativeTime: {
12217        future: function (str) {
12218            if (str.indexOf('un') === 0) {
12219                return 'n' + str;
12220            }
12221            return 'en ' + str;
12222        },
12223        past: 'hai %s',
12224        s: 'uns segundos',
12225        ss: '%d segundos',
12226        m: 'un minuto',
12227        mm: '%d minutos',
12228        h: 'unha hora',
12229        hh: '%d horas',
12230        d: 'un día',
12231        dd: '%d días',
12232        M: 'un mes',
12233        MM: '%d meses',
12234        y: 'un ano',
12235        yy: '%d anos',
12236    },
12237    dayOfMonthOrdinalParse: /\d{1,2}º/,
12238    ordinal: '%dº',
12239    week: {
12240        dow: 1, // Monday is the first day of the week.
12241        doy: 4, // The week that contains Jan 4th is the first week of the year.
12242    },
12243}));
12244
12245
12246/***/ }),
12247/* 63 */
12248/***/ (function(module, __webpack_exports__, __webpack_require__) {
12249
12250"use strict";
12251Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
12252/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
12253//! moment.js locale configuration
12254//! locale : Konkani Devanagari script [gom-deva]
12255//! author : The Discoverer : https://github.com/WikiDiscoverer
12256
12257
12258
12259function processRelativeTime(number, withoutSuffix, key, isFuture) {
12260    var format = {
12261        s: ['थोडया सॅकंडांनी', 'थोडे सॅकंड'],
12262        ss: [number + ' सॅकंडांनी', number + ' सॅकंड'],
12263        m: ['एका मिणटान', 'एक मिनूट'],
12264        mm: [number + ' मिणटांनी', number + ' मिणटां'],
12265        h: ['एका वरान', 'एक वर'],
12266        hh: [number + ' वरांनी', number + ' वरां'],
12267        d: ['एका दिसान', 'एक दीस'],
12268        dd: [number + ' दिसांनी', number + ' दीस'],
12269        M: ['एका म्हयन्यान', 'एक म्हयनो'],
12270        MM: [number + ' म्हयन्यानी', number + ' म्हयने'],
12271        y: ['एका वर्सान', 'एक वर्स'],
12272        yy: [number + ' वर्सांनी', number + ' वर्सां'],
12273    };
12274    return isFuture ? format[key][0] : format[key][1];
12275}
12276
12277/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('gom-deva', {
12278    months: {
12279        standalone: 'जानेवारी_फेब्रुवारी_मार्च_एप्रील_मे_जून_जुलय_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split(
12280            '_'
12281        ),
12282        format: 'जानेवारीच्या_फेब्रुवारीच्या_मार्चाच्या_एप्रीलाच्या_मेयाच्या_जूनाच्या_जुलयाच्या_ऑगस्टाच्या_सप्टेंबराच्या_ऑक्टोबराच्या_नोव्हेंबराच्या_डिसेंबराच्या'.split(
12283            '_'
12284        ),
12285        isFormat: /MMMM(\s)+D[oD]?/,
12286    },
12287    monthsShort: 'जाने._फेब्रु._मार्च_एप्री._मे_जून_जुल._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split(
12288        '_'
12289    ),
12290    monthsParseExact: true,
12291    weekdays: 'आयतार_सोमार_मंगळार_बुधवार_बिरेस्तार_सुक्राà
vendor: 8,846 bytes, lines 12291-12554
12291¤°_शेनवार'.split('_'),
12292    weekdaysShort: 'आयत._सोम._मंगळ._बुध._ब्रेस्त._सुक्र._शेन.'.split('_'),
12293    weekdaysMin: 'आ_सो_मं_बु_ब्रे_सु_शे'.split('_'),
12294    weekdaysParseExact: true,
12295    longDateFormat: {
12296        LT: 'A h:mm [वाजतां]',
12297        LTS: 'A h:mm:ss [वाजतां]',
12298        L: 'DD-MM-YYYY',
12299        LL: 'D MMMM YYYY',
12300        LLL: 'D MMMM YYYY A h:mm [वाजतां]',
12301        LLLL: 'dddd, MMMM Do, YYYY, A h:mm [वाजतां]',
12302        llll: 'ddd, D MMM YYYY, A h:mm [वाजतां]',
12303    },
12304    calendar: {
12305        sameDay: '[आयज] LT',
12306        nextDay: '[फाल्यां] LT',
12307        nextWeek: '[फुडलो] dddd[,] LT',
12308        lastDay: '[काल] LT',
12309        lastWeek: '[फाटलो] dddd[,] LT',
12310        sameElse: 'L',
12311    },
12312    relativeTime: {
12313        future: '%s',
12314        past: '%s आदीं',
12315        s: processRelativeTime,
12316        ss: processRelativeTime,
12317        m: processRelativeTime,
12318        mm: processRelativeTime,
12319        h: processRelativeTime,
12320        hh: processRelativeTime,
12321        d: processRelativeTime,
12322        dd: processRelativeTime,
12323        M: processRelativeTime,
12324        MM: processRelativeTime,
12325        y: processRelativeTime,
12326        yy: processRelativeTime,
12327    },
12328    dayOfMonthOrdinalParse: /\d{1,2}(वेर)/,
12329    ordinal: function (number, period) {
12330        switch (period) {
12331            // the ordinal 'वेर' only applies to day of the month
12332            case 'D':
12333                return number + 'वेर';
12334            default:
12335            case 'M':
12336            case 'Q':
12337            case 'DDD':
12338            case 'd':
12339            case 'w':
12340            case 'W':
12341                return number;
12342        }
12343    },
12344    week: {
12345        dow: 0, // Sunday is the first day of the week
12346        doy: 3, // The week that contains Jan 4th is the first week of the year (7 + 0 - 4)
12347    },
12348    meridiemParse: /राती|सकाळीं|दनपारां|सांजे/,
12349    meridiemHour: function (hour, meridiem) {
12350        if (hour === 12) {
12351            hour = 0;
12352        }
12353        if (meridiem === 'राती') {
12354            return hour < 4 ? hour : hour + 12;
12355        } else if (meridiem === 'सकाळीं') {
12356            return hour;
12357        } else if (meridiem === 'दनपारां') {
12358            return hour > 12 ? hour : hour + 12;
12359        } else if (meridiem === 'सांजे') {
12360            return hour + 12;
12361        }
12362    },
12363    meridiem: function (hour, minute, isLower) {
12364        if (hour < 4) {
12365            return 'राती';
12366        } else if (hour < 12) {
12367            return 'सकाळीं';
12368        } else if (hour < 16) {
12369            return 'दनपारां';
12370        } else if (hour < 20) {
12371            return 'सांजे';
12372        } else {
12373            return 'राती';
12374        }
12375    },
12376}));
12377
12378
12379/***/ }),
12380/* 64 */
12381/***/ (function(module, __webpack_exports__, __webpack_require__) {
12382
12383"use strict";
12384Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
12385/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
12386//! moment.js locale configuration
12387//! locale : Konkani Latin script [gom-latn]
12388//! author : The Discoverer : https://github.com/WikiDiscoverer
12389
12390
12391
12392function processRelativeTime(number, withoutSuffix, key, isFuture) {
12393    var format = {
12394        s: ['thoddea sekondamni', 'thodde sekond'],
12395        ss: [number + ' sekondamni', number + ' sekond'],
12396        m: ['eka mintan', 'ek minut'],
12397        mm: [number + ' mintamni', number + ' mintam'],
12398        h: ['eka voran', 'ek vor'],
12399        hh: [number + ' voramni', number + ' voram'],
12400        d: ['eka disan', 'ek dis'],
12401        dd: [number + ' disamni', number + ' dis'],
12402        M: ['eka mhoinean', 'ek mhoino'],
12403        MM: [number + ' mhoineamni', number + ' mhoine'],
12404        y: ['eka vorsan', 'ek voros'],
12405        yy: [number + ' vorsamni', number + ' vorsam'],
12406    };
12407    return isFuture ? format[key][0] : format[key][1];
12408}
12409
12410/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('gom-latn', {
12411    months: {
12412        standalone: 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split(
12413            '_'
12414        ),
12415        format: 'Janerachea_Febrerachea_Marsachea_Abrilachea_Maiachea_Junachea_Julaiachea_Agostachea_Setembrachea_Otubrachea_Novembrachea_Dezembrachea'.split(
12416            '_'
12417        ),
12418        isFormat: /MMMM(\s)+D[oD]?/,
12419    },
12420    monthsShort: 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split(
12421        '_'
12422    ),
12423    monthsParseExact: true,
12424    weekdays: "Aitar_Somar_Mongllar_Budhvar_Birestar_Sukrar_Son'var".split('_'),
12425    weekdaysShort: 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'),
12426    weekdaysMin: 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'),
12427    weekdaysParseExact: true,
12428    longDateFormat: {
12429        LT: 'A h:mm [vazta]',
12430        LTS: 'A h:mm:ss [vazta]',
12431        L: 'DD-MM-YYYY',
12432        LL: 'D MMMM YYYY',
12433        LLL: 'D MMMM YYYY A h:mm [vazta]',
12434        LLLL: 'dddd, MMMM Do, YYYY, A h:mm [vazta]',
12435        llll: 'ddd, D MMM YYYY, A h:mm [vazta]',
12436    },
12437    calendar: {
12438        sameDay: '[Aiz] LT',
12439        nextDay: '[Faleam] LT',
12440        nextWeek: '[Fuddlo] dddd[,] LT',
12441        lastDay: '[Kal] LT',
12442        lastWeek: '[Fattlo] dddd[,] LT',
12443        sameElse: 'L',
12444    },
12445    relativeTime: {
12446        future: '%s',
12447        past: '%s adim',
12448        s: processRelativeTime,
12449        ss: processRelativeTime,
12450        m: processRelativeTime,
12451        mm: processRelativeTime,
12452        h: processRelativeTime,
12453        hh: processRelativeTime,
12454        d: processRelativeTime,
12455        dd: processRelativeTime,
12456        M: processRelativeTime,
12457        MM: processRelativeTime,
12458        y: processRelativeTime,
12459        yy: processRelativeTime,
12460    },
12461    dayOfMonthOrdinalParse: /\d{1,2}(er)/,
12462    ordinal: function (number, period) {
12463        switch (period) {
12464            // the ordinal 'er' only applies to day of the month
12465            case 'D':
12466                return number + 'er';
12467            default:
12468            case 'M':
12469            case 'Q':
12470            case 'DDD':
12471            case 'd':
12472            case 'w':
12473            case 'W':
12474                return number;
12475        }
12476    },
12477    week: {
12478        dow: 0, // Sunday is the first day of the week
12479        doy: 3, // The week that contains Jan 4th is the first week of the year (7 + 0 - 4)
12480    },
12481    meridiemParse: /rati|sokallim|donparam|sanje/,
12482    meridiemHour: function (hour, meridiem) {
12483        if (hour === 12) {
12484            hour = 0;
12485        }
12486        if (meridiem === 'rati') {
12487            return hour < 4 ? hour : hour + 12;
12488        } else if (meridiem === 'sokallim') {
12489            return hour;
12490        } else if (meridiem === 'donparam') {
12491            return hour > 12 ? hour : hour + 12;
12492        } else if (meridiem === 'sanje') {
12493            return hour + 12;
12494        }
12495    },
12496    meridiem: function (hour, minute, isLower) {
12497        if (hour < 4) {
12498            return 'rati';
12499        } else if (hour < 12) {
12500            return 'sokallim';
12501        } else if (hour < 16) {
12502            return 'donparam';
12503        } else if (hour < 20) {
12504            return 'sanje';
12505        } else {
12506            return 'rati';
12507        }
12508    },
12509}));
12510
12511
12512/***/ }),
12513/* 65 */
12514/***/ (function(module, __webpack_exports__, __webpack_require__) {
12515
12516"use strict";
12517Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
12518/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
12519//! moment.js locale configuration
12520//! locale : Gujarati [gu]
12521//! author : Kaushik Thanki : https://github.com/Kaushik1987
12522
12523
12524
12525var symbolMap = {
12526        1: 'à«§',
12527        2: '૨',
12528        3: 'à«©',
12529        4: '૪',
12530        5: 'à««',
12531        6: '૬',
12532        7: 'à«­',
12533        8: 'à«®',
12534        9: '૯',
12535        0: '૦',
12536    },
12537    numberMap = {
12538        'à«§': '1',
12539        '૨': '2',
12540        'à«©': '3',
12541        '૪': '4',
12542        'à««': '5',
12543        '૬': '6',
12544        'à«­': '7',
12545        'à«®': '8',
12546        '૯': '9',
12547        '૦': '0',
12548    };
12549
12550/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('gu', {
12551    months: 'જાન્યુઆરી_ફેબ્રુઆરી_માર્ચ_એપ્રિલ_મે_જૂન_જુલાઈ_ઑગસ્ટ_સપ્ટેમ્બર_ઑક્ટ્બર_નવેમ્બર_ડિસેમ્બર'.split(
12552        '_'
12553    ),
12554    monthsShort: 'જાન્યુ._ફેબ્રુ._માર્ચ_એપ્રિ._મે_જૂન_જુલા._ઑગ._સપ્ટે._ઑક્ટ્._નવે._ડà
vendor: 6,878 bytes, lines 12554-12752
12554ª¿àª¸à«‡.'.split(
12555        '_'
12556    ),
12557    monthsParseExact: true,
12558    weekdays: 'રવિવાર_સોમવાર_મંગળવાર_બુધ્વાર_ગુરુવાર_શુક્રવાર_શનિવાર'.split(
12559        '_'
12560    ),
12561    weekdaysShort: 'રવિ_સોમ_મંગળ_બુધ્_ગુરુ_શુક્ર_શનિ'.split('_'),
12562    weekdaysMin: 'ર_સો_મં_બુ_ગુ_શુ_શ'.split('_'),
12563    longDateFormat: {
12564        LT: 'A h:mm વાગ્યે',
12565        LTS: 'A h:mm:ss વાગ્યે',
12566        L: 'DD/MM/YYYY',
12567        LL: 'D MMMM YYYY',
12568        LLL: 'D MMMM YYYY, A h:mm વાગ્યે',
12569        LLLL: 'dddd, D MMMM YYYY, A h:mm વાગ્યે',
12570    },
12571    calendar: {
12572        sameDay: '[આજ] LT',
12573        nextDay: '[કાલે] LT',
12574        nextWeek: 'dddd, LT',
12575        lastDay: '[ગઇકાલે] LT',
12576        lastWeek: '[પાછલા] dddd, LT',
12577        sameElse: 'L',
12578    },
12579    relativeTime: {
12580        future: '%s મા',
12581        past: '%s પહેલા',
12582        s: 'અમુક પળો',
12583        ss: '%d સેકંડ',
12584        m: 'એક મિનિટ',
12585        mm: '%d મિનિટ',
12586        h: 'એક કલાક',
12587        hh: '%d કલાક',
12588        d: 'એક દિવસ',
12589        dd: '%d દિવસ',
12590        M: 'એક મહિનો',
12591        MM: '%d મહિનો',
12592        y: 'એક વર્ષ',
12593        yy: '%d વર્ષ',
12594    },
12595    preparse: function (string) {
12596        return string.replace(/[૧૨૩૪૫૬૭૮૯૦]/g, function (match) {
12597            return numberMap[match];
12598        });
12599    },
12600    postformat: function (string) {
12601        return string.replace(/\d/g, function (match) {
12602            return symbolMap[match];
12603        });
12604    },
12605    // Gujarati notation for meridiems are quite fuzzy in practice. While there exists
12606    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Gujarati.
12607    meridiemParse: /રાત|બપોર|સવાર|સાંજ/,
12608    meridiemHour: function (hour, meridiem) {
12609        if (hour === 12) {
12610            hour = 0;
12611        }
12612        if (meridiem === 'રાત') {
12613            return hour < 4 ? hour : hour + 12;
12614        } else if (meridiem === 'સવાર') {
12615            return hour;
12616        } else if (meridiem === 'બપોર') {
12617            return hour >= 10 ? hour : hour + 12;
12618        } else if (meridiem === 'સાંજ') {
12619            return hour + 12;
12620        }
12621    },
12622    meridiem: function (hour, minute, isLower) {
12623        if (hour < 4) {
12624            return 'રાત';
12625        } else if (hour < 10) {
12626            return 'સવાર';
12627        } else if (hour < 17) {
12628            return 'બપોર';
12629        } else if (hour < 20) {
12630            return 'સાંજ';
12631        } else {
12632            return 'રાત';
12633        }
12634    },
12635    week: {
12636        dow: 0, // Sunday is the first day of the week.
12637        doy: 6, // The week that contains Jan 6th is the first week of the year.
12638    },
12639}));
12640
12641
12642/***/ }),
12643/* 66 */
12644/***/ (function(module, __webpack_exports__, __webpack_require__) {
12645
12646"use strict";
12647Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
12648/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
12649//! moment.js locale configuration
12650//! locale : Hebrew [he]
12651//! author : Tomer Cohen : https://github.com/tomer
12652//! author : Moshe Simantov : https://github.com/DevelopmentIL
12653//! author : Tal Ater : https://github.com/TalAter
12654
12655
12656
12657/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('he', {
12658    months: 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split(
12659        '_'
12660    ),
12661    monthsShort: 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split(
12662        '_'
12663    ),
12664    weekdays: 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),
12665    weekdaysShort: 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),
12666    weekdaysMin: 'א_ב_ג_ד_ה_ו_ש'.split('_'),
12667    longDateFormat: {
12668        LT: 'HH:mm',
12669        LTS: 'HH:mm:ss',
12670        L: 'DD/MM/YYYY',
12671        LL: 'D [ב]MMMM YYYY',
12672        LLL: 'D [ב]MMMM YYYY HH:mm',
12673        LLLL: 'dddd, D [ב]MMMM YYYY HH:mm',
12674        l: 'D/M/YYYY',
12675        ll: 'D MMM YYYY',
12676        lll: 'D MMM YYYY HH:mm',
12677        llll: 'ddd, D MMM YYYY HH:mm',
12678    },
12679    calendar: {
12680        sameDay: '[היום ב־]LT',
12681        nextDay: '[מחר ב־]LT',
12682        nextWeek: 'dddd [בשעה] LT',
12683        lastDay: '[אתמול ב־]LT',
12684        lastWeek: '[ביום] dddd [האחרון בשעה] LT',
12685        sameElse: 'L',
12686    },
12687    relativeTime: {
12688        future: 'בעוד %s',
12689        past: 'לפני %s',
12690        s: 'מספר שניות',
12691        ss: '%d שניות',
12692        m: 'דקה',
12693        mm: '%d דקות',
12694        h: 'שעה',
12695        hh: function (number) {
12696            if (number === 2) {
12697                return 'שעתיים';
12698            }
12699            return number + ' שעות';
12700        },
12701        d: 'יום',
12702        dd: function (number) {
12703            if (number === 2) {
12704                return 'יומיים';
12705            }
12706            return number + ' ימים';
12707        },
12708        M: 'חודש',
12709        MM: function (number) {
12710            if (number === 2) {
12711                return 'חודשיים';
12712            }
12713            return number + ' חודשים';
12714        },
12715        y: 'שנה',
12716        yy: function (number) {
12717            if (number === 2) {
12718                return 'שנתיים';
12719            } else if (number % 10 === 0 && number !== 10) {
12720                return number + ' שנה';
12721            }
12722            return number + ' שנים';
12723        },
12724    },
12725    meridiemParse: /אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,
12726    isPM: function (input) {
12727        return /^(אחה"צ|אחרי הצהריים|בערב)$/.test(input);
12728    },
12729    meridiem: function (hour, minute, isLower) {
12730        if (hour < 5) {
12731            return 'לפנות בוקר';
12732        } else if (hour < 10) {
12733            return 'בבוקר';
12734        } else if (hour < 12) {
12735            return isLower ? 'לפנה"צ' : 'לפני הצהריים';
12736        } else if (hour < 18) {
12737            return isLower ? 'אחה"צ' : 'אחרי הצהריים';
12738        } else {
12739            return 'בערב';
12740        }
12741    },
12742}));
12743
12744
12745/***/ }),
12746/* 67 */
12747/***/ (function(module, __webpack_exports__, __webpack_require__) {
12748
12749"use strict";
12750Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
12751/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
12752//! moment.js locale configuration
vendor: 5,515 bytes, lines 12753-12887
12753//! locale : Hindi [hi]
12754//! author : Mayank Singhal : https://github.com/mayanksinghal
12755
12756
12757
12758var symbolMap = {
12759        1: '१',
12760        2: '२',
12761        3: '३',
12762        4: '४',
12763        5: '५',
12764        6: '६',
12765        7: '७',
12766        8: '८',
12767        9: '९',
12768        0: '०',
12769    },
12770    numberMap = {
12771        '१': '1',
12772        '२': '2',
12773        '३': '3',
12774        '४': '4',
12775        '५': '5',
12776        '६': '6',
12777        '७': '7',
12778        '८': '8',
12779        '९': '9',
12780        '०': '0',
12781    },
12782    monthsParse = [
12783        /^जन/i,
12784        /^फ़र|फर/i,
12785        /^मार्च/i,
12786        /^अप्रै/i,
12787        /^मई/i,
12788        /^जून/i,
12789        /^जुल/i,
12790        /^अग/i,
12791        /^सितं|सित/i,
12792        /^अक्टू/i,
12793        /^नव|नवं/i,
12794        /^दिसं|दिस/i,
12795    ],
12796    shortMonthsParse = [
12797        /^जन/i,
12798        /^फ़र/i,
12799        /^मार्च/i,
12800        /^अप्रै/i,
12801        /^मई/i,
12802        /^जून/i,
12803        /^जुल/i,
12804        /^अग/i,
12805        /^सित/i,
12806        /^अक्टू/i,
12807        /^नव/i,
12808        /^दिस/i,
12809    ];
12810
12811/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('hi', {
12812    months: {
12813        format: 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split(
12814            '_'
12815        ),
12816        standalone: 'जनवरी_फरवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितंबर_अक्टूबर_नवंबर_दिसंबर'.split(
12817            '_'
12818        ),
12819    },
12820    monthsShort: 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split(
12821        '_'
12822    ),
12823    weekdays: 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
12824    weekdaysShort: 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),
12825    weekdaysMin: 'र_सो_मं_बु_गु_शु_श'.split('_'),
12826    longDateFormat: {
12827        LT: 'A h:mm बजे',
12828        LTS: 'A h:mm:ss बजे',
12829        L: 'DD/MM/YYYY',
12830        LL: 'D MMMM YYYY',
12831        LLL: 'D MMMM YYYY, A h:mm बजे',
12832        LLLL: 'dddd, D MMMM YYYY, A h:mm बजे',
12833    },
12834
12835    monthsParse: monthsParse,
12836    longMonthsParse: monthsParse,
12837    shortMonthsParse: shortMonthsParse,
12838
12839    monthsRegex: /^(जनवरी|जन\.?|फ़रवरी|फरवरी|फ़र\.?|मार्च?|अप्रैल|अप्रै\.?|मई?|जून?|जुलाई|जुल\.?|अगस्त|अग\.?|सितम्बर|सितंबर|सित\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर|नव\.?|दिसम्बर|दिसंबर|दिस\.?)/i,
12840
12841    monthsShortRegex: /^(जनवरी|जन\.?|फ़रवरी|फरवरी|फ़र\.?|मार्च?|अप्रैल|अप्रै\.?|मई?|जून?|जुलाई|जुल\.?|अगस्त|अग\.?|सितम्बर|सितंबर|सित\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर|नव\.?|दिसम्बर|दिसंबर|दिस\.?)/i,
12842
12843    monthsStrictRegex: /^(जनवरी?|फ़रवरी|फरवरी?|मार्च?|अप्रैल?|मई?|जून?|जुलाई?|अगस्त?|सितम्बर|सितंबर|सित?\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर?|दिसम्बर|दिसंबर?)/i,
12844
12845    monthsShortStrictRegex: /^(जन\.?|फ़र\.?|मार्च?|अप्रै\.?|मई?|जून?|जुल\.?|अग\.?|सित\.?|अक्टू\.?|नव\.?|दिस\.?)/i,
12846
12847    calendar: {
12848        sameDay: '[आज] LT',
12849        nextDay: '[कल] LT',
12850        nextWeek: 'dddd, LT',
12851        lastDay: '[कल] LT',
12852        lastWeek: '[पिछले] dddd, LT',
12853        sameElse: 'L',
12854    },
12855    relativeTime: {
12856        future: '%s में',
12857        past: '%s पहले',
12858        s: 'कुछ ही क्षण',
12859        ss: '%d सेकंड',
12860        m: 'एक मिनट',
12861        mm: '%d मिनट',
12862        h: 'एक घंटा',
12863        hh: '%d घंटे',
12864        d: 'एक दिन',
12865        dd: '%d दिन',
12866        M: 'एक महीने',
12867        MM: '%d महीने',
12868        y: 'एक वर्ष',
12869        yy: '%d वर्ष',
12870    },
12871    preparse: function (string) {
12872        return string.replace(/[१२३४५६७८९०]/g, function (match) {
12873            return numberMap[match];
12874        });
12875    },
12876    postformat: function (string) {
12877        return string.replace(/\d/g, function (match) {
12878            return symbolMap[match];
12879        });
12880    },
12881    // Hindi notation for meridiems are quite fuzzy in practice. While there exists
12882    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.
12883    meridiemParse: /रात|सुबह|दोपहर|शाम/,
12884    meridiemHour: function (hour, meridiem) {
12885        if (hour === 12) {
12886            hour = 0;
12887        }
vendor: 16,815 bytes, lines 12888-13411
12888        if (meridiem === 'रात') {
12889            return hour < 4 ? hour : hour + 12;
12890        } else if (meridiem === 'सुबह') {
12891            return hour;
12892        } else if (meridiem === 'दोपहर') {
12893            return hour >= 10 ? hour : hour + 12;
12894        } else if (meridiem === 'शाम') {
12895            return hour + 12;
12896        }
12897    },
12898    meridiem: function (hour, minute, isLower) {
12899        if (hour < 4) {
12900            return 'रात';
12901        } else if (hour < 10) {
12902            return 'सुबह';
12903        } else if (hour < 17) {
12904            return 'दोपहर';
12905        } else if (hour < 20) {
12906            return 'शाम';
12907        } else {
12908            return 'रात';
12909        }
12910    },
12911    week: {
12912        dow: 0, // Sunday is the first day of the week.
12913        doy: 6, // The week that contains Jan 6th is the first week of the year.
12914    },
12915}));
12916
12917
12918/***/ }),
12919/* 68 */
12920/***/ (function(module, __webpack_exports__, __webpack_require__) {
12921
12922"use strict";
12923Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
12924/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
12925//! moment.js locale configuration
12926//! locale : Croatian [hr]
12927//! author : Bojan Marković : https://github.com/bmarkovic
12928
12929
12930
12931function translate(number, withoutSuffix, key) {
12932    var result = number + ' ';
12933    switch (key) {
12934        case 'ss':
12935            if (number === 1) {
12936                result += 'sekunda';
12937            } else if (number === 2 || number === 3 || number === 4) {
12938                result += 'sekunde';
12939            } else {
12940                result += 'sekundi';
12941            }
12942            return result;
12943        case 'm':
12944            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
12945        case 'mm':
12946            if (number === 1) {
12947                result += 'minuta';
12948            } else if (number === 2 || number === 3 || number === 4) {
12949                result += 'minute';
12950            } else {
12951                result += 'minuta';
12952            }
12953            return result;
12954        case 'h':
12955            return withoutSuffix ? 'jedan sat' : 'jednog sata';
12956        case 'hh':
12957            if (number === 1) {
12958                result += 'sat';
12959            } else if (number === 2 || number === 3 || number === 4) {
12960                result += 'sata';
12961            } else {
12962                result += 'sati';
12963            }
12964            return result;
12965        case 'dd':
12966            if (number === 1) {
12967                result += 'dan';
12968            } else {
12969                result += 'dana';
12970            }
12971            return result;
12972        case 'MM':
12973            if (number === 1) {
12974                result += 'mjesec';
12975            } else if (number === 2 || number === 3 || number === 4) {
12976                result += 'mjeseca';
12977            } else {
12978                result += 'mjeseci';
12979            }
12980            return result;
12981        case 'yy':
12982            if (number === 1) {
12983                result += 'godina';
12984            } else if (number === 2 || number === 3 || number === 4) {
12985                result += 'godine';
12986            } else {
12987                result += 'godina';
12988            }
12989            return result;
12990    }
12991}
12992
12993/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('hr', {
12994    months: {
12995        format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split(
12996            '_'
12997        ),
12998        standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split(
12999            '_'
13000        ),
13001    },
13002    monthsShort: 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split(
13003        '_'
13004    ),
13005    monthsParseExact: true,
13006    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split(
13007        '_'
13008    ),
13009    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
13010    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),
13011    weekdaysParseExact: true,
13012    longDateFormat: {
13013        LT: 'H:mm',
13014        LTS: 'H:mm:ss',
13015        L: 'DD.MM.YYYY',
13016        LL: 'Do MMMM YYYY',
13017        LLL: 'Do MMMM YYYY H:mm',
13018        LLLL: 'dddd, Do MMMM YYYY H:mm',
13019    },
13020    calendar: {
13021        sameDay: '[danas u] LT',
13022        nextDay: '[sutra u] LT',
13023        nextWeek: function () {
13024            switch (this.day()) {
13025                case 0:
13026                    return '[u] [nedjelju] [u] LT';
13027                case 3:
13028                    return '[u] [srijedu] [u] LT';
13029                case 6:
13030                    return '[u] [subotu] [u] LT';
13031                case 1:
13032                case 2:
13033                case 4:
13034                case 5:
13035                    return '[u] dddd [u] LT';
13036            }
13037        },
13038        lastDay: '[jučer u] LT',
13039        lastWeek: function () {
13040            switch (this.day()) {
13041                case 0:
13042                    return '[prošlu] [nedjelju] [u] LT';
13043                case 3:
13044                    return '[prošlu] [srijedu] [u] LT';
13045                case 6:
13046                    return '[prošle] [subote] [u] LT';
13047                case 1:
13048                case 2:
13049                case 4:
13050                case 5:
13051                    return '[prošli] dddd [u] LT';
13052            }
13053        },
13054        sameElse: 'L',
13055    },
13056    relativeTime: {
13057        future: 'za %s',
13058        past: 'prije %s',
13059        s: 'par sekundi',
13060        ss: translate,
13061        m: translate,
13062        mm: translate,
13063        h: translate,
13064        hh: translate,
13065        d: 'dan',
13066        dd: translate,
13067        M: 'mjesec',
13068        MM: translate,
13069        y: 'godinu',
13070        yy: translate,
13071    },
13072    dayOfMonthOrdinalParse: /\d{1,2}\./,
13073    ordinal: '%d.',
13074    week: {
13075        dow: 1, // Monday is the first day of the week.
13076        doy: 7, // The week that contains Jan 7th is the first week of the year.
13077    },
13078}));
13079
13080
13081/***/ }),
13082/* 69 */
13083/***/ (function(module, __webpack_exports__, __webpack_require__) {
13084
13085"use strict";
13086Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
13087/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
13088//! moment.js locale configuration
13089//! locale : Hungarian [hu]
13090//! author : Adam Brunner : https://github.com/adambrunner
13091//! author : Peter Viszt  : https://github.com/passatgt
13092
13093
13094
13095var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(
13096    ' '
13097);
13098function translate(number, withoutSuffix, key, isFuture) {
13099    var num = number;
13100    switch (key) {
13101        case 's':
13102            return isFuture || withoutSuffix
13103                ? 'néhány másodperc'
13104                : 'néhány másodperce';
13105        case 'ss':
13106            return num + (isFuture || withoutSuffix)
13107                ? ' másodperc'
13108                : ' másodperce';
13109        case 'm':
13110            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');
13111        case 'mm':
13112            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');
13113        case 'h':
13114            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');
13115        case 'hh':
13116            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');
13117        case 'd':
13118            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');
13119        case 'dd':
13120            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');
13121        case 'M':
13122            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
13123        case 'MM':
13124            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
13125        case 'y':
13126            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');
13127        case 'yy':
13128            return num + (isFuture || withoutSuffix ? ' év' : ' éve');
13129    }
13130    return '';
13131}
13132function week(isFuture) {
13133    return (
13134        (isFuture ? '' : '[múlt] ') +
13135        '[' +
13136        weekEndings[this.day()] +
13137        '] LT[-kor]'
13138    );
13139}
13140
13141/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('hu', {
13142    months: 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split(
13143        '_'
13144    ),
13145    monthsShort: 'jan._feb._márc._ápr._máj._jún._júl._aug._szept._okt._nov._dec.'.split(
13146        '_'
13147    ),
13148    monthsParseExact: true,
13149    weekdays: 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),
13150    weekdaysShort: 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),
13151    weekdaysMin: 'v_h_k_sze_cs_p_szo'.split('_'),
13152    longDateFormat: {
13153        LT: 'H:mm',
13154        LTS: 'H:mm:ss',
13155        L: 'YYYY.MM.DD.',
13156        LL: 'YYYY. MMMM D.',
13157        LLL: 'YYYY. MMMM D. H:mm',
13158        LLLL: 'YYYY. MMMM D., dddd H:mm',
13159    },
13160    meridiemParse: /de|du/i,
13161    isPM: function (input) {
13162        return input.charAt(1).toLowerCase() === 'u';
13163    },
13164    meridiem: function (hours, minutes, isLower) {
13165        if (hours < 12) {
13166            return isLower === true ? 'de' : 'DE';
13167        } else {
13168            return isLower === true ? 'du' : 'DU';
13169        }
13170    },
13171    calendar: {
13172        sameDay: '[ma] LT[-kor]',
13173        nextDay: '[holnap] LT[-kor]',
13174        nextWeek: function () {
13175            return week.call(this, true);
13176        },
13177        lastDay: '[tegnap] LT[-kor]',
13178        lastWeek: function () {
13179            return week.call(this, false);
13180        },
13181        sameElse: 'L',
13182    },
13183    relativeTime: {
13184        future: '%s múlva',
13185        past: '%s',
13186        s: translate,
13187        ss: translate,
13188        m: translate,
13189        mm: translate,
13190        h: translate,
13191        hh: translate,
13192        d: translate,
13193        dd: translate,
13194        M: translate,
13195        MM: translate,
13196        y: translate,
13197        yy: translate,
13198    },
13199    dayOfMonthOrdinalParse: /\d{1,2}\./,
13200    ordinal: '%d.',
13201    week: {
13202        dow: 1, // Monday is the first day of the week.
13203        doy: 4, // The week that contains Jan 4th is the first week of the year.
13204    },
13205}));
13206
13207
13208/***/ }),
13209/* 70 */
13210/***/ (function(module, __webpack_exports__, __webpack_require__) {
13211
13212"use strict";
13213Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
13214/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
13215//! moment.js locale configuration
13216//! locale : Armenian [hy-am]
13217//! author : Armendarabyan : https://github.com/armendarabyan
13218
13219
13220
13221/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('hy-am', {
13222    months: {
13223        format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split(
13224            '_'
13225        ),
13226        standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split(
13227            '_'
13228        ),
13229    },
13230    monthsShort: 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),
13231    weekdays: 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split(
13232        '_'
13233    ),
13234    weekdaysShort: 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
13235    weekdaysMin: 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
13236    longDateFormat: {
13237        LT: 'HH:mm',
13238        LTS: 'HH:mm:ss',
13239        L: 'DD.MM.YYYY',
13240        LL: 'D MMMM YYYY Õ©.',
13241        LLL: 'D MMMM YYYY Õ©., HH:mm',
13242        LLLL: 'dddd, D MMMM YYYY Õ©., HH:mm',
13243    },
13244    calendar: {
13245        sameDay: '[այսօր] LT',
13246        nextDay: '[Õ¾Õ¡Õ²Õ¨] LT',
13247        lastDay: '[երեկ] LT',
13248        nextWeek: function () {
13249            return 'dddd [օրը ժամը] LT';
13250        },
13251        lastWeek: function () {
13252            return '[անցած] dddd [օրը ժամը] LT';
13253        },
13254        sameElse: 'L',
13255    },
13256    relativeTime: {
13257        future: '%s Õ°Õ¥Õ¿Õ¸',
13258        past: '%s Õ¡Õ¼Õ¡Õ»',
13259        s: 'մի քանի վայրկյան',
13260        ss: '%d վայրկյան',
13261        m: 'րոպե',
13262        mm: '%d րոպե',
13263        h: 'ÕªÕ¡Õ´',
13264        hh: '%d ÕªÕ¡Õ´',
13265        d: 'օր',
13266        dd: '%d օր',
13267        M: 'Õ¡Õ´Õ«Õ½',
13268        MM: '%d Õ¡Õ´Õ«Õ½',
13269        y: 'տարի',
13270        yy: '%d տարի',
13271    },
13272    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,
13273    isPM: function (input) {
13274        return /^(ցերեկվա|երեկոյան)$/.test(input);
13275    },
13276    meridiem: function (hour) {
13277        if (hour < 4) {
13278            return 'գիշերվա';
13279        } else if (hour < 12) {
13280            return 'Õ¡Õ¼Õ¡Õ¾Õ¸Õ¿Õ¾Õ¡';
13281        } else if (hour < 17) {
13282            return 'ցերեկվա';
13283        } else {
13284            return 'երեկոյան';
13285        }
13286    },
13287    dayOfMonthOrdinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/,
13288    ordinal: function (number, period) {
13289        switch (period) {
13290            case 'DDD':
13291            case 'w':
13292            case 'W':
13293            case 'DDDo':
13294                if (number === 1) {
13295                    return number + '-Õ«Õ¶';
13296                }
13297                return number + '-րդ';
13298            default:
13299                return number;
13300        }
13301    },
13302    week: {
13303        dow: 1, // Monday is the first day of the week.
13304        doy: 7, // The week that contains Jan 7th is the first week of the year.
13305    },
13306}));
13307
13308
13309/***/ }),
13310/* 71 */
13311/***/ (function(module, __webpack_exports__, __webpack_require__) {
13312
13313"use strict";
13314Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
13315/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
13316//! moment.js locale configuration
13317//! locale : Indonesian [id]
13318//! author : Mohammad Satrio Utomo : https://github.com/tyok
13319//! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan
13320
13321
13322
13323/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('id', {
13324    months: 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split(
13325        '_'
13326    ),
13327    monthsShort: 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agt_Sep_Okt_Nov_Des'.split('_'),
13328    weekdays: 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),
13329    weekdaysShort: 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),
13330    weekdaysMin: 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),
13331    longDateFormat: {
13332        LT: 'HH.mm',
13333        LTS: 'HH.mm.ss',
13334        L: 'DD/MM/YYYY',
13335        LL: 'D MMMM YYYY',
13336        LLL: 'D MMMM YYYY [pukul] HH.mm',
13337        LLLL: 'dddd, D MMMM YYYY [pukul] HH.mm',
13338    },
13339    meridiemParse: /pagi|siang|sore|malam/,
13340    meridiemHour: function (hour, meridiem) {
13341        if (hour === 12) {
13342            hour = 0;
13343        }
13344        if (meridiem === 'pagi') {
13345            return hour;
13346        } else if (meridiem === 'siang') {
13347            return hour >= 11 ? hour : hour + 12;
13348        } else if (meridiem === 'sore' || meridiem === 'malam') {
13349            return hour + 12;
13350        }
13351    },
13352    meridiem: function (hours, minutes, isLower) {
13353        if (hours < 11) {
13354            return 'pagi';
13355        } else if (hours < 15) {
13356            return 'siang';
13357        } else if (hours < 19) {
13358            return 'sore';
13359        } else {
13360            return 'malam';
13361        }
13362    },
13363    calendar: {
13364        sameDay: '[Hari ini pukul] LT',
13365        nextDay: '[Besok pukul] LT',
13366        nextWeek: 'dddd [pukul] LT',
13367        lastDay: '[Kemarin pukul] LT',
13368        lastWeek: 'dddd [lalu pukul] LT',
13369        sameElse: 'L',
13370    },
13371    relativeTime: {
13372        future: 'dalam %s',
13373        past: '%s yang lalu',
13374        s: 'beberapa detik',
13375        ss: '%d detik',
13376        m: 'semenit',
13377        mm: '%d menit',
13378        h: 'sejam',
13379        hh: '%d jam',
13380        d: 'sehari',
13381        dd: '%d hari',
13382        M: 'sebulan',
13383        MM: '%d bulan',
13384        y: 'setahun',
13385        yy: '%d tahun',
13386    },
13387    week: {
13388        dow: 0, // Sunday is the first day of the week.
13389        doy: 6, // The week that contains Jan 6th is the first week of the year.
13390    },
13391}));
13392
13393
13394/***/ }),
13395/* 72 */
13396/***/ (function(module, __webpack_exports__, __webpack_require__) {
13397
13398"use strict";
13399Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
13400/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
13401//! moment.js locale configuration
13402//! locale : Icelandic [is]
13403//! author : Hinrik Örn Sigurðsson : https://github.com/hinrik
13404
13405
13406
13407function plural(n) {
13408    if (n % 100 === 11) {
13409        return true;
13410    } else if (n % 10 === 1) {
13411        return false;
vendor: 4,587 bytes, lines 13412-13550
13412    }
13413    return true;
13414}
13415function translate(number, withoutSuffix, key, isFuture) {
13416    var result = number + ' ';
13417    switch (key) {
13418        case 's':
13419            return withoutSuffix || isFuture
13420                ? 'nokkrar sekúndur'
13421                : 'nokkrum sekúndum';
13422        case 'ss':
13423            if (plural(number)) {
13424                return (
13425                    result +
13426                    (withoutSuffix || isFuture ? 'sekúndur' : 'sekúndum')
13427                );
13428            }
13429            return result + 'sekúnda';
13430        case 'm':
13431            return withoutSuffix ? 'mínúta' : 'mínútu';
13432        case 'mm':
13433            if (plural(number)) {
13434                return (
13435                    result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum')
13436                );
13437            } else if (withoutSuffix) {
13438                return result + 'mínúta';
13439            }
13440            return result + 'mínútu';
13441        case 'hh':
13442            if (plural(number)) {
13443                return (
13444                    result +
13445                    (withoutSuffix || isFuture
13446                        ? 'klukkustundir'
13447                        : 'klukkustundum')
13448                );
13449            }
13450            return result + 'klukkustund';
13451        case 'd':
13452            if (withoutSuffix) {
13453                return 'dagur';
13454            }
13455            return isFuture ? 'dag' : 'degi';
13456        case 'dd':
13457            if (plural(number)) {
13458                if (withoutSuffix) {
13459                    return result + 'dagar';
13460                }
13461                return result + (isFuture ? 'daga' : 'dögum');
13462            } else if (withoutSuffix) {
13463                return result + 'dagur';
13464            }
13465            return result + (isFuture ? 'dag' : 'degi');
13466        case 'M':
13467            if (withoutSuffix) {
13468                return 'mánuður';
13469            }
13470            return isFuture ? 'mánuð' : 'mánuði';
13471        case 'MM':
13472            if (plural(number)) {
13473                if (withoutSuffix) {
13474                    return result + 'mánuðir';
13475                }
13476                return result + (isFuture ? 'mánuði' : 'mánuðum');
13477            } else if (withoutSuffix) {
13478                return result + 'mánuður';
13479            }
13480            return result + (isFuture ? 'mánuð' : 'mánuði');
13481        case 'y':
13482            return withoutSuffix || isFuture ? 'ár' : 'ári';
13483        case 'yy':
13484            if (plural(number)) {
13485                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');
13486            }
13487            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');
13488    }
13489}
13490
13491/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('is', {
13492    months: 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split(
13493        '_'
13494    ),
13495    monthsShort: 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),
13496    weekdays: 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split(
13497        '_'
13498    ),
13499    weekdaysShort: 'sun_mán_þri_mið_fim_fös_lau'.split('_'),
13500    weekdaysMin: 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),
13501    longDateFormat: {
13502        LT: 'H:mm',
13503        LTS: 'H:mm:ss',
13504        L: 'DD.MM.YYYY',
13505        LL: 'D. MMMM YYYY',
13506        LLL: 'D. MMMM YYYY [kl.] H:mm',
13507        LLLL: 'dddd, D. MMMM YYYY [kl.] H:mm',
13508    },
13509    calendar: {
13510        sameDay: '[í dag kl.] LT',
13511        nextDay: '[á morgun kl.] LT',
13512        nextWeek: 'dddd [kl.] LT',
13513        lastDay: '[í gær kl.] LT',
13514        lastWeek: '[síðasta] dddd [kl.] LT',
13515        sameElse: 'L',
13516    },
13517    relativeTime: {
13518        future: 'eftir %s',
13519        past: 'fyrir %s síðan',
13520        s: translate,
13521        ss: translate,
13522        m: translate,
13523        mm: translate,
13524        h: 'klukkustund',
13525        hh: translate,
13526        d: translate,
13527        dd: translate,
13528        M: translate,
13529        MM: translate,
13530        y: translate,
13531        yy: translate,
13532    },
13533    dayOfMonthOrdinalParse: /\d{1,2}\./,
13534    ordinal: '%d.',
13535    week: {
13536        dow: 1, // Monday is the first day of the week.
13537        doy: 4, // The week that contains Jan 4th is the first week of the year.
13538    },
13539}));
13540
13541
13542/***/ }),
13543/* 73 */
13544/***/ (function(module, __webpack_exports__, __webpack_require__) {
13545
13546"use strict";
13547Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
13548/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
13549//! moment.js locale configuration
13550//! locale : Italian [it]
13551//! author : Lorenzo : https://github.com/aliem
13552//! author: Mattia Larentis: https://github.com/nostalgiaz
13553//! author: Marco : https://github.com/Manfre98
13554
13555
13556
13557/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('it', {
13558    months: 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split(
13559        '_'
13560    ),
13561    monthsShort: 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),
13562    weekdays: 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split(
13563        '_'
13564    ),
13565    weekdaysShort: 'dom_lun_mar_mer_gio_ven_sab'.split('_'),
13566    weekdaysMin: 'do_lu_ma_me_gi_ve_sa'.split('_'),
13567    longDateFormat: {
13568        LT: 'HH:mm',
13569        LTS: 'HH:mm:ss',
13570        L: 'DD/MM/YYYY',
13571        LL: 'D MMMM YYYY',
13572        LLL: 'D MMMM YYYY HH:mm',
13573        LLLL: 'dddd D MMMM YYYY HH:mm',
13574    },
13575    calendar: {
13576        sameDay: function () {
13577            return (
13578                '[Oggi a' +
13579                (this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") +
13580                ']LT'
13581            );
13582        },
13583        nextDay: function () {
13584            return (
13585                '[Domani a' +
13586                (this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") +
13587                ']LT'
13588            );
13589        },
13590        nextWeek: function () {
13591            return (
13592                'dddd [a' +
13593                (this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") +
13594                ']LT'
13595            );
13596        },
13597        lastDay: function () {
13598            return (
13599                '[Ieri a' +
13600                (this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") +
13601                ']LT'
13602            );
13603        },
13604        lastWeek: function () {
13605            switch (this.day()) {
13606                case 0:
13607                    return (
13608                        '[La scorsa] dddd [a' +
13609                        (this.hours() > 1
13610                            ? 'lle '
13611                            : this.hours() === 0
13612                            ? ' '
13613                            : "ll'") +
13614                        ']LT'
13615                    );
13616                default:
13617                    return (
13618                        '[Lo scorso] dddd [a' +
13619                        (this.hours() > 1
13620                            ? 'lle '
13621                            : this.hours() === 0
13622                            ? ' '
13623                            : "ll'") +
13624                        ']LT'
13625                    );
13626            }
13627        },
13628        sameElse: 'L',
13629    },
13630    relativeTime: {
13631        future: 'tra %s',
13632        past: '%s fa',
13633        s: 'alcuni secondi',
13634        ss: '%d secondi',
13635        m: 'un minuto',
13636        mm: '%d minuti',
13637        h: "un'ora",
13638        hh: '%d ore',
13639        d: 'un giorno',
13640        dd: '%d giorni',
13641        w: 'una settimana',
13642        ww: '%d settimane',
13643        M: 'un mese',
13644        MM: '%d mesi',
13645        y: 'un anno',
13646        yy: '%d anni',
13647    },
13648    dayOfMonthOrdinalParse: /\d{1,2}º/,
13649    ordinal: '%dº',
13650    week: {
13651        dow: 1, // Monday is the first day of the week.
13652        doy: 4, // The week that contains Jan 4th is the first week of the year.
13653    },
13654}));
13655
13656
13657/***/ }),
13658/* 74 */
13659/***/ (function(module, __webpack_exports__, __webpack_require__) {
13660
13661"use strict";
13662Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
13663/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
13664//! moment.js locale configuration
13665//! locale : Italian (Switzerland) [it-ch]
13666//! author : xfh : https://github.com/xfh
13667
13668
13669
13670/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('it-ch', {
13671    months: 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split(
13672        '_'
13673    ),
13674    monthsShort: 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),
13675    weekdays: 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split(
13676        '_'
13677    ),
13678    weekdaysShort: 'dom_lun_mar_mer_gio_ven_sab'.split('_'),
13679    weekdaysMin: 'do_lu_ma_me_gi_ve_sa'.split('_'),
13680    longDateFormat: {
13681        LT: 'HH:mm',
13682        LTS: 'HH:mm:ss',
13683        L: 'DD.MM.YYYY',
13684        LL: 'D MMMM YYYY',
13685        LLL: 'D MMMM YYYY HH:mm',
13686        LLLL: 'dddd D MMMM YYYY HH:mm',
13687    },
13688    calendar: {
13689        sameDay: '[Oggi alle] LT',
13690        nextDay: '[Domani alle] LT',
13691        nextWeek: 'dddd [alle] LT',
13692        lastDay: '[Ieri alle] LT',
13693        lastWeek: function () {
13694            switch (this.day()) {
13695                case 0:
13696                    return '[la scorsa] dddd [alle] LT';
13697                default:
13698                    return '[lo scorso] dddd [alle] LT';
13699            }
13700        },
13701        sameElse: 'L',
13702    },
13703    relativeTime: {
13704        future: function (s) {
13705            return (/^[0-9].+$/.test(s) ? 'tra' : 'in') + ' ' + s;
13706        },
13707        past: '%s fa',
13708        s: 'alcuni secondi',
13709        ss: '%d secondi',
13710        m: 'un minuto',
13711        mm: '%d minuti',
13712        h: "un'ora",
13713        hh: '%d ore',
13714        d: 'un giorno',
13715        dd: '%d giorni',
13716        M: 'un mese',
13717        MM: '%d mesi',
13718        y: 'un anno',
13719        yy: '%d anni',
13720    },
13721    dayOfMonthOrdinalParse: /\d{1,2}º/,
13722    ordinal: '%dº',
13723    week: {
13724        dow: 1, // Monday is the first day of the week.
13725        doy: 4, // The week that contains Jan 4th is the first week of the year.
13726    },
13727}));
13728
13729
13730/***/ }),
13731/* 75 */
13732/***/ (function(module, __webpack_exports__, __webpack_require__) {
13733
13734"use strict";
13735Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
13736/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
13737//! moment.js locale configuration
13738//! locale : Japanese [ja]
13739//! author : LI Long : https://github.com/baryon
13740
13741
13742
13743/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ja', {
13744    eras: [
13745        {
13746            since: '2019-05-01',
13747            offset: 1,
13748            name: '令和',
13749            narrow: '㋿',
13750            abbr: 'R',
13751        },
13752        {
13753            since: '1989-01-08',
13754            until: '2019-04-30',
13755            offset: 1,
13756            name: '平成',
13757            narrow: '㍻',
13758            abbr: 'H',
13759        },
13760        {
13761            since: '1926-12-25',
13762            until: '1989-01-07',
13763            offset: 1,
13764            name: '昭和',
13765            narrow: '㍼',
13766            abbr: 'S',
13767        },
13768        {
13769            since: '1912-07-30',
13770            until: '1926-12-24',
13771            offset: 1,
13772            name: '大正',
13773            narrow: '㍽',
13774            abbr: 'T',
13775        },
13776        {
13777            since: '1873-01-01',
13778            until: '1912-07-29',
13779            offset: 6,
13780            name: '明治',
13781            narrow: '㍾',
13782            abbr: 'M',
13783        },
13784        {
13785            since: '0001-01-01',
13786            until: '1873-12-31',
13787            offset: 1,
13788            name: '西暦',
13789            narrow: 'AD',
13790            abbr: 'AD',
13791        },
13792        {
13793            since: '0000-12-31',
13794            until: -Infinity,
13795            offset: 1,
13796            name: '紀元前',
13797            narrow: 'BC',
13798            abbr: 'BC',
13799        },
13800    ],
13801    eraYearOrdinalRegex: /(元|\d+)年/,
13802    eraYearOrdinalParse: function (input, match) {
13803        return match[1] === '元' ? 1 : parseInt(match[1] || input, 10);
13804    },
13805    months: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
13806    monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(
13807        '_'
13808    ),
13809    weekdays: '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),
13810    weekdaysShort: '日_月_火_水_木_金_土'.split('_'),
13811    weekdaysMin: '日_月_火_水_木_金_土'.split('_'),
13812    longDateFormat: {
13813        LT: 'HH:mm',
13814        LTS: 'HH:mm:ss',
13815        L: 'YYYY/MM/DD',
13816        LL: 'YYYY年M月D日',
13817        LLL: 'YYYY年M月D日 HH:mm',
13818        LLLL: 'YYYY年M月D日 dddd HH:mm',
13819        l: 'YYYY/MM/DD',
13820        ll: 'YYYY年M月D日',
13821        lll: 'YYYY年M月D日 HH:mm',
13822        llll: 'YYYY年M月D日(ddd) HH:mm',
13823    },
13824    meridiemParse: /午前|午後/i,
13825    isPM: function (input) {
13826        return input === '午後';
13827    },
13828    meridiem: function (hour, minute, isLower) {
13829        if (hour < 12) {
13830            return '午前';
13831        } else {
13832            return '午後';
13833        }
13834    },
13835    calendar: {
13836        sameDay: '[今日] LT',
13837        nextDay: '[明日] LT',
13838        nextWeek: function (now) {
13839            if (now.week() !== this.week()) {
13840                return '[来週]dddd LT';
13841            } else {
13842                return 'dddd LT';
13843            }
13844        },
13845        lastDay: '[昨日] LT',
13846        lastWeek: function (now) {
13847            if (this.week() !== now.week()) {
13848                return '[先週]dddd LT';
13849            } else {
13850                return 'dddd LT';
13851            }
13852        },
13853        sameElse: 'L',
13854    },
13855    dayOfMonthOrdinalParse: /\d{1,2}日/,
13856    ordinal: function (number, period) {
13857        switch (period) {
13858            case 'y':
13859                return number === 1 ? '元年' : number + '年';
13860            case 'd':
13861            case 'D':
13862            case 'DDD':
13863                return number + '日';
13864            default:
13865                return number;
13866        }
13867    },
13868    relativeTime: {
13869        future: '%s後',
13870        past: '%s前',
13871        s: '数秒',
13872        ss: '%d秒',
13873        m: '1分',
13874        mm: '%d分',
13875        h: '1時間',
13876        hh: '%d時間',
13877        d: '1日',
13878        dd: '%d日',
13879        M: '1ヶ月',
13880        MM: '%dヶ月',
13881        y: '1å¹´',
13882        yy: '%då¹´',
13883    },
13884}));
13885
13886
13887/***/ }),
13888/* 76 */
13889/***/ (function(module, __webpack_exports__, __webpack_require__) {
13890
13891"use strict";
13892Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
13893/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
13894//! moment.js locale configuration
13895//! locale : Javanese [jv]
13896//! author : Rony Lantip : https://github.com/lantip
13897//! reference: http://jv.wikipedia.org/wiki/Basa_Jawa
13898
13899
13900
13901/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('jv', {
13902    months: 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split(
13903        '_'
13904    ),
13905    monthsShort: 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'),
13906    weekdays: 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'),
13907    weekdaysShort: 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'),
13908    weekdaysMin: 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),
13909    longDateFormat: {
13910        LT: 'HH.mm',
13911        LTS: 'HH.mm.ss',
13912        L: 'DD/MM/YYYY',
13913        LL: 'D MMMM YYYY',
13914        LLL: 'D MMMM YYYY [pukul] HH.mm',
13915        LLLL: 'dddd, D MMMM YYYY [pukul] HH.mm',
13916    },
13917    meridiemParse: /enjing|siyang|sonten|ndalu/,
13918    meridiemHour: function (hour, meridiem) {
13919        if (hour === 12) {
13920            hour = 0;
13921        }
13922        if (meridiem === 'enjing') {
13923            return hour;
13924        } else if (meridiem === 'siyang') {
13925            return hour >= 11 ? hour : hour + 12;
13926        } else if (meridiem === 'sonten' || meridiem === 'ndalu') {
13927            return hour + 12;
13928        }
13929    },
13930    meridiem: function (hours, minutes, isLower) {
13931        if (hours < 11) {
13932            return 'enjing';
13933        } else if (hours < 15) {
13934            return 'siyang';
13935        } else if (hours < 19) {
13936            return 'sonten';
13937        } else {
13938            return 'ndalu';
13939        }
13940    },
13941    calendar: {
13942        sameDay: '[Dinten puniko pukul] LT',
13943        nextDay: '[Mbenjang pukul] LT',
13944        nextWeek: 'dddd [pukul] LT',
13945        lastDay: '[Kala wingi pukul] LT',
13946        lastWeek: 'dddd [kepengker pukul] LT',
13947        sameElse: 'L',
13948    },
13949    relativeTime: {
13950        future: 'wonten ing %s',
13951        past: '%s ingkang kepengker',
13952        s: 'sawetawis detik',
13953        ss: '%d detik',
13954        m: 'setunggal menit',
13955        mm: '%d menit',
13956        h: 'setunggal jam',
13957        hh: '%d jam',
13958        d: 'sedinten',
13959        dd: '%d dinten',
13960        M: 'sewulan',
13961        MM: '%d wulan',
13962        y: 'setaun',
13963        yy: '%d taun',
13964    },
13965    week: {
13966        dow: 1, // Monday is the first day of the week.
13967        doy: 7, // The week that contains Jan 7th is the first week of the year.
13968    },
13969}));
13970
13971
13972/***/ }),
13973/* 77 */
13974/***/ (function(module, __webpack_exports__, __webpack_require__) {
13975
13976"use strict";
13977Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
13978/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
13979//! moment.js locale configuration
13980//! locale : Georgian [ka]
13981//! author : Irakli Janiashvili : https://github.com/IrakliJani
13982
13983
13984
13985/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ka', {
13986    months: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split(
13987        '_'
13988    ),
13989    monthsShort: 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),
13990    weekdays: {
13991        standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.
13991split(
13992            '_'
13993        ),
13994        format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split(
13995            '_'
13996        ),
13997        isFormat: /(წინა|შემდეგ)/,
13998    },
13999    weekdaysShort: 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),
14000    weekdaysMin: 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),
14001    longDateFormat: {
14002        LT: 'HH:mm',
14003        LTS: 'HH:mm:ss',
14004        L: 'DD/MM/YYYY',
14005        LL: 'D MMMM YYYY',
14006        LLL: 'D MMMM YYYY HH:mm',
14007        LLLL: 'dddd, D MMMM YYYY HH:mm',
14008    },
14009    calendar: {
14010        sameDay: '[დღეს] LT[-ზე]',
14011        nextDay: '[ხვალ] LT[-ზე]',
14012        lastDay: '[გუშინ] LT[-ზე]',
14013        nextWeek: '[შემდეგ] dddd LT[-ზე]',
14014        lastWeek: '[წინა] dddd LT-ზე',
14015        sameElse: 'L',
14016    },
14017    relativeTime: {
14018        future: function (s) {
14019            return s.replace(/(წამ|წუთ|საათ|წელ|დღ|თვ)(ი|ე)/, function (
14020                $0,
14021                $1,
14022                $2
14023            ) {
14024                return $2 === 'ი' ? $1 + 'ში' : $1 + $2 + 'ში';
14025            });
14026        },
14027        past: function (s) {
14028            if (/(წამი|წუთი|საათი|დღე|თვე)/.test(s)) {
14029                return s.replace(/(ი|ე)$/, 'ის წინ');
14030            }
14031            if (/წელი/.test(s)) {
14032                return s.replace(/წელი$/, 'წლის წინ');
14033            }
14034            return s;
14035        },
14036        s: 'რამდენიმე წამი',
14037        ss: '%d წამი',
14038        m: 'წუთი',
14039        mm: '%d წუთი',
14040        h: 'საათი',
14041        hh: '%d საათი',
14042        d: 'დღე',
14043        dd: '%d დღე',
14044        M: 'თვე',
14045        MM: '%d თვე',
14046        y: 'წელი',
14047        yy: '%d წელი',
14048    },
14049    dayOfMonthOrdinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/,
14050    ordinal: function (number) {
14051        if (number === 0) {
14052            return number;
14053        }
14054        if (number === 1) {
14055            return number + '-ლი';
14056        }
14057        if (
14058            number < 20 ||
14059            (number <= 100 && number % 20 === 0) ||
14060            number % 100 === 0
14061        ) {
14062            return 'მე-' + number;
14063        }
14064        return number + '-ე';
14065    },
14066    week: {
14067        dow: 1,
14068        doy: 7,
14069    },
14070}));
14071
14072
14073/***/ }),
14074/* 78 */
14075/***/ (function(module, __webpack_exports__, __webpack_require__) {
14076
14077"use strict";
14078Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
14079/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
14080//! moment.js locale configuration
14081//! locale : Kazakh [kk]
14082//! authors : Nurlan Rakhimzhanov : https://github.com/nurlan
14083
14084
14085
14086var suffixes = {
14087    0: '-ші',
14088    1: '-ші',
14089    2: '-ші',
14090    3: '-ші',
14091    4: '-ші',
14092    5: '-ші',
14093    6: '-шы',
14094    7: '-ші',
14095    8: '-ші',
14096    9: '-шы',
14097    10: '-шы',
14098    20: '-шы',
14099    30: '-шы',
14100    40: '-шы',
14101    50: '-ші',
14102    60: '-шы',
14103    70: '-ші',
14104    80: '-ші',
14105    90: '-шы',
14106    100: '-ші',
14107};
14108
14109/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('kk', {
14110    months: 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split(
14111        '_'
14112    ),
14113    monthsShort: 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'),
14114    weekdays: 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split(
14115        '_'
14116    ),
14117    weekdaysShort: 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'),
14118    weekdaysMin: 'жк_дй_сй_ср_бй_жм_сн'.split('_'),
14119    longDateFormat: {
14120        LT: 'HH:mm',
14121        LTS: 'HH:mm:ss',
14122        L: 'DD.MM.YYYY',
14123        LL: 'D MMMM YYYY',
14124        LLL: 'D MMMM YYYY HH:mm',
14125        LLLL: 'dddd, D MMMM YYYY HH:mm',
14126    },
14127    calendar: {
14128        sameDay: '[Бүгін сағат] LT',
14129        nextDay: '[Ертең сағат] LT',
14130        nextWeek: 'dddd [сағат] LT',
14131        lastDay: '[Кеше сағат] LT',
14132        lastWeek: '[Өткен аптаның] dddd [сағат] LT',
14133        sameElse: 'L',
14134    },
14135    relativeTime: {
14136        future: '%s ішінде',
14137        past: '%s бұрын',
14138        s: 'бірнеше секунд',
14139        ss: '%d секунд',
14140        m: 'бір минут',
14141        mm: '%d минут',
14142        h: 'бір сағат',
14143        hh: '%d сағат',
14144        d: 'бір күн',
14145        dd: '%d күн',
14146        M: 'бір ай',
14147        MM: '%d ай',
14148        y: 'бір жыл',
14149        yy: '%d жыл',
14150    },
14151    dayOfMonthOrdinalParse: /\d{1,2}-(ші|шы)/,
14152    ordinal: function (number) {
14153        var a = number % 10,
14154            b = number >= 100 ? 100 : null;
14155        return number + (suffixes[number] || suffixes[a] || suffixes[b]);
14156    },
14157    week: {
14158        dow: 1, // Monday is the first day of the week.
14159        doy: 7, // The week that contains Jan 7th is the first week of the year.
14160    },
14161}));
14162
14163
14164/***/ }),
14165/* 79 */
14166/***/ (function(module, __webpack_exports__, __webpack_require__) {
14167
14168"use strict";
14169Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
14170/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
14171//! moment.js locale configuration
14172//! locale : Cambodian [km]
14173//! author : Kruy Vanna : https://github.com/kruyvanna
14174
14175
14176
14177var symbolMap = {
14178        1: '១',
14179        2: '២',
14180        3: '៣',
14181        4: '៤',
14182        5: '៥',
14183        6: '៦',
14184        7: '៧',
14185        8: '៨',
14186        9: '៩',
14187        0: '០',
14188    },
14189    numberMap = {
14190        '១': '1',
14191        '២': '2',
14192        '៣': '3',
14193        '៤': '4',
14194        '៥': '5',
14195        '៦': '6',
14196        '៧': '7',
14197        '៨': '8',
14198        '៩': '9',
14199        '០': '0',
14200    };
14201
14202/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('km', {
14203    months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split(
14204        '_'
14205    ),
14206    monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split(
14207        '_'
14208    ),
14209    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
14210    weekdaysShort: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'),
14211    weekdaysMin: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'),
14212    weekdaysParseExact: true,
14213    longDateFormat: {
14214        LT: 'HH:mm',
14215        LTS: 'HH:mm:ss',
14216        L: 'DD/MM/YYYY',
14217        LL: 'D MMMM YYYY',
14218        LLL: 'D MMMM YYYY HH:mm',
14219        LLLL: 'dddd, D MMMM YYYY HH:mm',
14220    },
14221    meridiemParse: /ព្រឹក|ល្ងាច/,
14222    isPM: function (input) {
14223        return input === 'ល្ងាច';
14224    },
14225    meridiem: function (hour, minute, isLower) {
14226        if (hour < 12) {
vendor: 15,974 bytes, lines 14227-14734
14227            return 'ព្រឹក';
14228        } else {
14229            return 'ល្ងាច';
14230        }
14231    },
14232    calendar: {
14233        sameDay: '[ថ្ងៃនេះ ម៉ោង] LT',
14234        nextDay: '[ស្អែក ម៉ោង] LT',
14235        nextWeek: 'dddd [ម៉ោង] LT',
14236        lastDay: '[ម្សិលមិញ ម៉ោង] LT',
14237        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',
14238        sameElse: 'L',
14239    },
14240    relativeTime: {
14241        future: '%sទៀត',
14242        past: '%sមុន',
14243        s: 'ប៉ុន្មានវិនាទី',
14244        ss: '%d វិនាទី',
14245        m: 'មួយនាទី',
14246        mm: '%d នាទី',
14247        h: 'មួយម៉ោង',
14248        hh: '%d ម៉ោង',
14249        d: 'មួយថ្ងៃ',
14250        dd: '%d ថ្ងៃ',
14251        M: 'មួយខែ',
14252        MM: '%d ខែ',
14253        y: 'មួយឆ្នាំ',
14254        yy: '%d ឆ្នាំ',
14255    },
14256    dayOfMonthOrdinalParse: /ទី\d{1,2}/,
14257    ordinal: 'ទី%d',
14258    preparse: function (string) {
14259        return string.replace(/[១២៣៤៥៦៧៨៩០]/g, function (match) {
14260            return numberMap[match];
14261        });
14262    },
14263    postformat: function (string) {
14264        return string.replace(/\d/g, function (match) {
14265            return symbolMap[match];
14266        });
14267    },
14268    week: {
14269        dow: 1, // Monday is the first day of the week.
14270        doy: 4, // The week that contains Jan 4th is the first week of the year.
14271    },
14272}));
14273
14274
14275/***/ }),
14276/* 80 */
14277/***/ (function(module, __webpack_exports__, __webpack_require__) {
14278
14279"use strict";
14280Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
14281/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
14282//! moment.js locale configuration
14283//! locale : Kannada [kn]
14284//! author : Rajeev Naik : https://github.com/rajeevnaikte
14285
14286
14287
14288var symbolMap = {
14289        1: 'à³§',
14290        2: '೨',
14291        3: '೩',
14292        4: '೪',
14293        5: '೫',
14294        6: '೬',
14295        7: 'à³­',
14296        8: 'à³®',
14297        9: '೯',
14298        0: '೦',
14299    },
14300    numberMap = {
14301        'à³§': '1',
14302        '೨': '2',
14303        '೩': '3',
14304        '೪': '4',
14305        '೫': '5',
14306        '೬': '6',
14307        'à³­': '7',
14308        'à³®': '8',
14309        '೯': '9',
14310        '೦': '0',
14311    };
14312
14313/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('kn', {
14314    months: 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split(
14315        '_'
14316    ),
14317    monthsShort: 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂ_ಅಕ್ಟೋ_ನವೆಂ_ಡಿಸೆಂ'.split(
14318        '_'
14319    ),
14320    monthsParseExact: true,
14321    weekdays: 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split(
14322        '_'
14323    ),
14324    weekdaysShort: 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'),
14325    weekdaysMin: 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'),
14326    longDateFormat: {
14327        LT: 'A h:mm',
14328        LTS: 'A h:mm:ss',
14329        L: 'DD/MM/YYYY',
14330        LL: 'D MMMM YYYY',
14331        LLL: 'D MMMM YYYY, A h:mm',
14332        LLLL: 'dddd, D MMMM YYYY, A h:mm',
14333    },
14334    calendar: {
14335        sameDay: '[ಇಂದು] LT',
14336        nextDay: '[ನಾಳೆ] LT',
14337        nextWeek: 'dddd, LT',
14338        lastDay: '[ನಿನ್ನೆ] LT',
14339        lastWeek: '[ಕೊನೆಯ] dddd, LT',
14340        sameElse: 'L',
14341    },
14342    relativeTime: {
14343        future: '%s ನಂತರ',
14344        past: '%s ಹಿಂದೆ',
14345        s: 'ಕೆಲವು ಕ್ಷಣಗಳು',
14346        ss: '%d ಸೆಕೆಂಡುಗಳು',
14347        m: 'ಒಂದು ನಿಮಿಷ',
14348        mm: '%d ನಿಮಿಷ',
14349        h: 'ಒಂದು ಗಂಟೆ',
14350        hh: '%d ಗಂಟೆ',
14351        d: 'ಒಂದು ದಿನ',
14352        dd: '%d ದಿನ',
14353        M: 'ಒಂದು ತಿಂಗಳು',
14354        MM: '%d ತಿಂಗಳು',
14355        y: 'ಒಂದು ವರ್ಷ',
14356        yy: '%d ವರ್ಷ',
14357    },
14358    preparse: function (string) {
14359        return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) {
14360            return numberMap[match];
14361        });
14362    },
14363    postformat: function (string) {
14364        return string.replace(/\d/g, function (match) {
14365            return symbolMap[match];
14366        });
14367    },
14368    meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,
14369    meridiemHour: function (hour, meridiem) {
14370        if (hour === 12) {
14371            hour = 0;
14372        }
14373        if (meridiem === 'ರಾತ್ರಿ') {
14374            return hour < 4 ? hour : hour + 12;
14375        } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') {
14376            return hour;
14377        } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') {
14378            return hour >= 10 ? hour : hour + 12;
14379        } else if (meridiem === 'ಸಂಜೆ') {
14380            return hour + 12;
14381        }
14382    },
14383    meridiem: function (hour, minute, isLower) {
14384        if (hour < 4) {
14385            return 'ರಾತ್ರಿ';
14386        } else if (hour < 10) {
14387            return 'ಬೆಳಿಗ್ಗೆ';
14388        } else if (hour < 17) {
14389            return 'ಮಧ್ಯಾಹ್ನ';
14390        } else if (hour < 20) {
14391            return 'ಸಂಜೆ';
14392        } else {
14393            return 'ರಾತ್ರಿ';
14394        }
14395    },
14396    dayOfMonthOrdinalParse: /\d{1,2}(ನೇ)/,
14397    ordinal: function (number) {
14398        return number + 'ನೇ';
14399    },
14400    week: {
14401        dow: 0, // Sunday is the first day of the week.
14402        doy: 6, // The week that contains Jan 6th is the first week of the year.
14403    },
14404}));
14405
14406
14407/***/ }),
14408/* 81 */
14409/***/ (function(module, __webpack_exports__, __webpack_require__) {
14410
14411"use strict";
14412Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
14413/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
14414//! moment.js locale configuration
14415//! locale : Korean [ko]
14416//! author : Kyungwook, Park : https://github.com/kyungw00k
14417//! author : Jeeeyul Lee <[email protected]>
14418
14419
14420
14421/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ko', {
14422    months: '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),
14423    monthsShort: '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split(
14424        '_'
14425    ),
14426    weekdays: '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),
14427    weekdaysShort: '일_월_화_수_목_금_토'.split('_'),
14428    weekdaysMin: '일_월_화_수_목_금_토'.split('_'),
14429    longDateFormat: {
14430        LT: 'A h:mm',
14431        LTS: 'A h:mm:ss',
14432        L: 'YYYY.MM.DD.',
14433        LL: 'YYYY년 MMMM D일',
14434        LLL: 'YYYY년 MMMM D일 A h:mm',
14435        LLLL: 'YYYY년 MMMM D일 dddd A h:mm',
14436        l: 'YYYY.MM.DD.',
14437        ll: 'YYYY년 MMMM D일',
14438        lll: 'YYYY년 MMMM D일 A h:mm',
14439        llll: 'YYYY년 MMMM D일 dddd A h:mm',
14440    },
14441    calendar: {
14442        sameDay: '오늘 LT',
14443        nextDay: '내일 LT',
14444        nextWeek: 'dddd LT',
14445        lastDay: '어제 LT',
14446        lastWeek: '지난주 dddd LT',
14447        sameElse: 'L',
14448    },
14449    relativeTime: {
14450        future: '%s 후',
14451        past: '%s 전',
14452        s: '몇 초',
14453        ss: '%d초',
14454        m: '1분',
14455        mm: '%d분',
14456        h: '한 시간',
14457        hh: '%d시간',
14458        d: '하루',
14459        dd: '%d일',
14460        M: '한 달',
14461        MM: '%d달',
14462        y: '일 년',
14463        yy: '%d년',
14464    },
14465    dayOfMonthOrdinalParse: /\d{1,2}(일|월|주)/,
14466    ordinal: function (number, period) {
14467        switch (period) {
14468            case 'd':
14469            case 'D':
14470            case 'DDD':
14471                return number + '일';
14472            case 'M':
14473                return number + '월';
14474            case 'w':
14475            case 'W':
14476                return number + '주';
14477            default:
14478                return number;
14479        }
14480    },
14481    meridiemParse: /오전|오후/,
14482    isPM: function (token) {
14483        return token === '오후';
14484    },
14485    meridiem: function (hour, minute, isUpper) {
14486        return hour < 12 ? '오전' : '오후';
14487    },
14488}));
14489
14490
14491/***/ }),
14492/* 82 */
14493/***/ (function(module, __webpack_exports__, __webpack_require__) {
14494
14495"use strict";
14496Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
14497/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
14498//! moment.js locale configuration
14499//! locale : Kurdish [ku]
14500//! author : Shahram Mebashar : https://github.com/ShahramMebashar
14501
14502
14503
14504var symbolMap = {
14505        1: 'Ù¡',
14506        2: 'Ù¢',
14507        3: 'Ù£',
14508        4: 'Ù¤',
14509        5: 'Ù¥',
14510        6: 'Ù¦',
14511        7: 'Ù§',
14512        8: 'Ù¨',
14513        9: 'Ù©',
14514        0: 'Ù ',
14515    },
14516    numberMap = {
14517        'Ù¡': '1',
14518        'Ù¢': '2',
14519        'Ù£': '3',
14520        'Ù¤': '4',
14521        'Ù¥': '5',
14522        'Ù¦': '6',
14523        'Ù§': '7',
14524        'Ù¨': '8',
14525        'Ù©': '9',
14526        'Ù ': '0',
14527    },
14528    months = [
14529        'کانونی دووەم',
14530        'شوبات',
14531        'ئازار',
14532        'نیسان',
14533        'ئایار',
14534        'حوزەیران',
14535        'تەمموز',
14536        'ئاب',
14537        'ئەیلوول',
14538        'تشرینی یەكەم',
14539        'تشرینی دووەم',
14540        'كانونی یەکەم',
14541    ];
14542
14543/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ku', {
14544    months: months,
14545    monthsShort: months,
14546    weekdays: 'یه‌كشه‌ممه‌_دووشه‌ممه‌_سێشه‌ممه‌_چوارشه‌ممه‌_پێنجشه‌ممه‌_هه‌ینی_شه‌ممه‌'.split(
14547        '_'
14548    ),
14549    weekdaysShort: 'یه‌كشه‌م_دووشه‌م_سێشه‌م_چوارشه‌م_پێنجشه‌م_هه‌ینی_شه‌ممه‌'.split(
14550        '_'
14551    ),
14552    weekdaysMin: 'ی_د_س_چ_پ_ه_ش'.split('_'),
14553    weekdaysParseExact: true,
14554    longDateFormat: {
14555        LT: 'HH:mm',
14556        LTS: 'HH:mm:ss',
14557        L: 'DD/MM/YYYY',
14558        LL: 'D MMMM YYYY',
14559        LLL: 'D MMMM YYYY HH:mm',
14560        LLLL: 'dddd, D MMMM YYYY HH:mm',
14561    },
14562    meridiemParse: /ئێواره‌|به‌یانی/,
14563    isPM: function (input) {
14564        return /ئێواره‌/.test(input);
14565    },
14566    meridiem: function (hour, minute, isLower) {
14567        if (hour < 12) {
14568            return 'به‌یانی';
14569        } else {
14570            return 'ئێواره‌';
14571        }
14572    },
14573    calendar: {
14574        sameDay: '[ئه‌مرۆ كاتژمێر] LT',
14575        nextDay: '[به‌یانی كاتژمێر] LT',
14576        nextWeek: 'dddd [كاتژمێر] LT',
14577        lastDay: '[دوێنێ كاتژمێر] LT',
14578        lastWeek: 'dddd [كاتژمێر] LT',
14579        sameElse: 'L',
14580    },
14581    relativeTime: {
14582        future: 'له‌ %s',
14583        past: '%s',
14584        s: 'چه‌ند چركه‌یه‌ك',
14585        ss: 'چركه‌ %d',
14586        m: 'یه‌ك خوله‌ك',
14587        mm: '%d خوله‌ك',
14588        h: 'یه‌ك كاتژمێر',
14589        hh: '%d كاتژمێر',
14590        d: 'یه‌ك ڕۆژ',
14591        dd: '%d ڕۆژ',
14592        M: 'یه‌ك مانگ',
14593        MM: '%d مانگ',
14594        y: 'یه‌ك ساڵ',
14595        yy: '%d ساڵ',
14596    },
14597    preparse: function (string) {
14598        return string
14599            .replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
14600                return numberMap[match];
14601            })
14602            .replace(/،/g, ',');
14603    },
14604    postformat: function (string) {
14605        return string
14606            .replace(/\d/g, function (match) {
14607                return symbolMap[match];
14608            })
14609            .replace(/,/g, '،');
14610    },
14611    week: {
14612        dow: 6, // Saturday is the first day of the week.
14613        doy: 12, // The week that contains Jan 12th is the first week of the year.
14614    },
14615}));
14616
14617
14618/***/ }),
14619/* 83 */
14620/***/ (function(module, __webpack_exports__, __webpack_require__) {
14621
14622"use strict";
14623Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
14624/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
14625//! moment.js locale configuration
14626//! locale : Kyrgyz [ky]
14627//! author : Chyngyz Arystan uulu : https://github.com/chyngyz
14628
14629
14630
14631var suffixes = {
14632    0: '-чү',
14633    1: '-чи',
14634    2: '-чи',
14635    3: '-чү',
14636    4: '-чү',
14637    5: '-чи',
14638    6: '-чы',
14639    7: '-чи',
14640    8: '-чи',
14641    9: '-чу',
14642    10: '-чу',
14643    20: '-чы',
14644    30: '-чу',
14645    40: '-чы',
14646    50: '-чү',
14647    60: '-чы',
14648    70: '-чи',
14649    80: '-чи',
14650    90: '-чу',
14651    100: '-чү',
14652};
14653
14654/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ky', {
14655    months: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split(
14656        '_'
14657    ),
14658    monthsShort: 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split(
14659        '_'
14660    ),
14661    weekdays: 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split(
14662        '_'
14663    ),
14664    weekdaysShort: 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'),
14665    weekdaysMin: 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'),
14666    longDateFormat: {
14667        LT: 'HH:mm',
14668        LTS: 'HH:mm:ss',
14669        L: 'DD.MM.YYYY',
14670        LL: 'D MMMM YYYY',
14671        LLL: 'D MMMM YYYY HH:mm',
14672        LLLL: 'dddd, D MMMM YYYY HH:mm',
14673    },
14674    calendar: {
14675        sameDay: '[Бүгүн саат] LT',
14676        nextDay: '[Эртең саат] LT',
14677        nextWeek: 'dddd [саат] LT',
14678        lastDay: '[Кечээ саат] LT',
14679        lastWeek: '[Өткөн аптанын] dddd [күнү] [саат] LT',
14680        sameElse: 'L',
14681    },
14682    relativeTime: {
14683        future: '%s ичинде',
14684        past: '%s мурун',
14685        s: 'бирнече секунд',
14686        ss: '%d секунд',
14687        m: 'бир мүнөт',
14688        mm: '%d мүнөт',
14689        h: 'бир саат',
14690        hh: '%d саат',
14691        d: 'бир күн',
14692        dd: '%d күн',
14693        M: 'бир ай',
14694        MM: '%d ай',
14695        y: 'бир жыл',
14696        yy: '%d жыл',
14697    },
14698    dayOfMonthOrdinalParse: /\d{1,2}-(чи|чы|чү|чу)/,
14699    ordinal: function (number) {
14700        var a = number % 10,
14701            b = number >= 100 ? 100 : null;
14702        return number + (suffixes[number] || suffixes[a] || suffixes[b]);
14703    },
14704    week: {
14705        dow: 1, // Monday is the first day of the week.
14706        doy: 7, // The week that contains Jan 7th is the first week of the year.
14707    },
14708}));
14709
14710
14711/***/ }),
14712/* 84 */
14713/***/ (function(module, __webpack_exports__, __webpack_require__) {
14714
14715"use strict";
14716Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
14717/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
14718//! moment.js locale configuration
14719//! locale : Luxembourgish [lb]
14720//! author : mweimerskirch : https://github.com/mweimerskirch
14721//! author : David Raison : https://github.com/kwisatz
14722
14723
14724
14725function processRelativeTime(number, withoutSuffix, key, isFuture) {
14726    var format = {
14727        m: ['eng Minutt', 'enger Minutt'],
14728        h: ['eng Stonn', 'enger Stonn'],
14729        d: ['een Dag', 'engem Dag'],
14730        M: ['ee Mount', 'engem Mount'],
14731        y: ['ee Joer', 'engem Joer'],
14732    };
14733    return withoutSuffix ? format[key][0] : format[key][1];
14734}
14735function processFutureTime(string) {
14736    var number = string.substr(0, string.indexOf(' '));
14737    if (eifelerRegelAppliesToNumber(number)) {
14738        return 'a ' + string;
14739    }
14740    return 'an ' + string;
14741}
14742function processPastTime(string) {
14743    var number = string.substr(0, string.indexOf(' '));
14744    if (eifelerRegelAppliesToNumber(number)) {
14745        return 'viru ' + string;
14746    }
14747    return 'virun ' + string;
14748}
14749/**
14750 * Returns true if the word before the given number loses the '-n' ending.
14751 * e.g. 'an 10 Deeg' but 'a 5 Deeg'
14752 *
14753 * @param number {integer}
14754 * @returns {boolean}
14755 */
14756function eifelerRegelAppliesToNumber(number) {
14757    number = parseInt(number, 10);
14758    if (isNaN(number)) {
14759        return false;
14760    }
14761    if (number < 0) {
14762        // Negative Number --> always true
14763        return true;
14764    } else if (number < 10) {
14765        // Only 1 digit
14766        if (4 <= number && number <= 7) {
14767            return true;
14768        }
14769        return false;
14770    } else if (number < 100) {
14771        // 2 digits
14772        var lastDigit = number % 10,
14773            firstDigit = number / 10;
14774        if (lastDigit === 0) {
14775            return eifelerRegelAppliesToNumber(firstDigit);
14776        }
14777        return eifelerRegelAppliesToNumber(lastDigit);
14778    } else if (number < 10000) {
14779        // 3 or 4 digits --> recursively check first digit
14780        while (number >= 10) {
14781            number = number / 10;
14782        }
14783        return eifelerRegelAppliesToNumber(number);
14784    } else {
14785        // Anything larger than 4 digits: recursively check first n-3 digits
14786        number = number / 1000;
14787        return eifelerRegelAppliesToNumber(number);
14788    }
14789}
14790
14791/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('lb', {
14792    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split(
14793        '_'
14794    ),
14795    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split(
14796        '_'
14797    ),
14798    monthsParseExact: true,
14799    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split(
14800        '_'
14801    ),
14802    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),
14803    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),
14804    weekdaysParseExact: true,
14805    longDateFormat: {
14806        LT: 'H:mm [Auer]',
14807        LTS: 'H:mm:ss [Auer]',
14808        L: 'DD.MM.YYYY',
14809        LL: 'D. MMMM YYYY',
14810        LLL: 'D. MMMM YYYY H:mm [Auer]',
14811        LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]',
14812    },
14813    calendar: {
14814        sameDay: '[Haut um] LT',
14815        sameElse: 'L',
14816        nextDay: '[Muer um] LT',
14817        nextWeek: 'dddd [um] LT',
14818        lastDay: '[Gëschter um] LT',
14819        lastWeek: function () {
14820            // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule
14821            switch (this.day()) {
14822                case 2:
14823                case 4:
14824                    return '[Leschten] dddd [um] LT';
14825                default:
14826                    return '[Leschte] dddd [um] LT';
14827            }
14828        },
14829    },
14830    relativeTime: {
14831        future: processFutureTime,
14832        past: processPastTime,
14833        s: 'e puer Sekonnen',
14834        ss: '%d Sekonnen',
14835        m: processRelativeTime,
14836        mm: '%d Minutten',
14837        h: processRelativeTime,
14838        hh: '%d Stonnen',
14839        d: processRelativeTime,
14840        dd: '%d Deeg',
14841        M: processRelativeTime,
14842        MM: '%d Méint',
14843        y: processRelativeTime,
14844        yy: '%d Joer',
14845    },
14846    dayOfMonthOrdinalParse: /\d{1,2}\./,
14847    ordinal: '%d.',
14848    week: {
14849        dow: 1, // Monday is the first day of the week.
14850        doy: 4, // The week that contains Jan 4th is the first week of the year.
14851    },
14852}));
14853
14854
14855/***/ }),
14856/* 85 */
14857/***/ (function(module, __webpack_exports__, __webpack_require__) {
14858
14859"use strict";
14860Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
14861/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
14862//! moment.js locale configuration
14863//! locale : Lao [lo]
14864//! author : Ryan Hart : https://github.com/ryanhart2
14865
14866
14867
14868/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('lo', {
14869    months: 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split(
14870        '_'
14871    ),
14872    monthsShort: 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split(
14873        '_'
14874    ),
14875    weekdays: 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),
14876    weekdaysShort: 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'),
14877    weekdaysMin: 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'),
14878    weekdaysParseExact: true,
14879    longDateFormat: {
14880        LT: 'HH:mm',
14881        LTS: 'HH:mm:ss',
14882        L: 'DD/MM/YYYY',
14883        LL: 'D MMMM YYYY',
14884        LLL: 'D MMMM YYYY HH:mm',
14885        LLLL: 'ວັນdddd D MMMM YYYY HH:mm',
14886    },
14887    meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/,
14888    isPM: function (input) {
14889        return input === 'ຕອນແລງ';
14890    },
14891    meridiem: function (hour, minute, isLower) {
14892        if (hour < 12) {
14893            return 'ຕອນເຊົ້າ';
14894        } else {
14895            return 'ຕອນແລງ';
14896        }
14897    },
14898    calendar: {
14899        sameDay: '[ມື້ນີ້ເວລາ] LT',
14900        nextDay: '[ມື້ອື່ນເວລາ] LT',
14901        nextWeek: '[ວັນ]dddd[ໜ້າເວລາ] LT',
14902        lastDay: '[ມື້ວານນີ້ເວລາ] LT',
14903        lastWeek: '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT',
14904        sameElse: 'L',
14905    },
14906    relativeTime: {
14907        future: 'ອີກ %s',
14908        past: '%sຜ່ານມາ',
14909        s: 'ບໍ່ເທົ່າໃດວິນາທີ',
14910        ss: '%d ວິນາທີ',
14911        m: '1 ນາທີ',
14912        mm: '%d ນາທີ',
14913        h: '1 ຊົ່ວໂມງ',
14914        hh: '%d ຊົ່ວໂມງ',
14915        d: '1 ມື້',
14916        dd: '%d ມື້',
14917        M: '1 ເດືອນ',
14918        MM: '%d ເດືອນ',
14919        y: '1 ປີ',
14920        yy: '%d ປີ',
14921    },
14922    dayOfMonthOrdinalParse: /(ທີ່)\d{1,2}/,
14923    ordinal: function (number) {
14924        return 'ທີ່' + number;
14925    },
14926}));
14927
14928
14929/***/ }),
14930/* 86 */
14931/***/ (function(module, __webpack_exports__, __webpack_require__) {
14932
14933"use strict";
14934Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
14935/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
14936//! moment.js locale configuration
14937//! locale : Lithuanian [lt]
14938//! author : Mindaugas Mozūras : https://github.com/mmozuras
14939
14940
14941
14942var units = {
14943    ss: 'sekundė_sekundžių_sekundes',
14944    m: 'minutė_minutės_minutę',
14945    mm: 'minutės_minučių_minutes',
14946    h: 'valanda_valandos_valandą',
14947    hh: 'valandos_valandų_valandas',
vendor: 4,443 bytes, lines 14948-15080
14948    d: 'diena_dienos_dieną',
14949    dd: 'dienos_dienų_dienas',
14950    M: 'mėnuo_mėnesio_mėnesį',
14951    MM: 'mėnesiai_mėnesių_mėnesius',
14952    y: 'metai_metų_metus',
14953    yy: 'metai_metų_metus',
14954};
14955function translateSeconds(number, withoutSuffix, key, isFuture) {
14956    if (withoutSuffix) {
14957        return 'kelios sekundės';
14958    } else {
14959        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';
14960    }
14961}
14962function translateSingular(number, withoutSuffix, key, isFuture) {
14963    return withoutSuffix
14964        ? forms(key)[0]
14965        : isFuture
14966        ? forms(key)[1]
14967        : forms(key)[2];
14968}
14969function special(number) {
14970    return number % 10 === 0 || (number > 10 && number < 20);
14971}
14972function forms(key) {
14973    return units[key].split('_');
14974}
14975function translate(number, withoutSuffix, key, isFuture) {
14976    var result = number + ' ';
14977    if (number === 1) {
14978        return (
14979            result + translateSingular(number, withoutSuffix, key[0], isFuture)
14980        );
14981    } else if (withoutSuffix) {
14982        return result + (special(number) ? forms(key)[1] : forms(key)[0]);
14983    } else {
14984        if (isFuture) {
14985            return result + forms(key)[1];
14986        } else {
14987            return result + (special(number) ? forms(key)[1] : forms(key)[2]);
14988        }
14989    }
14990}
14991/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('lt', {
14992    months: {
14993        format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split(
14994            '_'
14995        ),
14996        standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split(
14997            '_'
14998        ),
14999        isFormat: /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/,
15000    },
15001    monthsShort: 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),
15002    weekdays: {
15003        format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split(
15004            '_'
15005        ),
15006        standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split(
15007            '_'
15008        ),
15009        isFormat: /dddd HH:mm/,
15010    },
15011    weekdaysShort: 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),
15012    weekdaysMin: 'S_P_A_T_K_Pn_Å '.split('_'),
15013    weekdaysParseExact: true,
15014    longDateFormat: {
15015        LT: 'HH:mm',
15016        LTS: 'HH:mm:ss',
15017        L: 'YYYY-MM-DD',
15018        LL: 'YYYY [m.] MMMM D [d.]',
15019        LLL: 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
15020        LLLL: 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',
15021        l: 'YYYY-MM-DD',
15022        ll: 'YYYY [m.] MMMM D [d.]',
15023        lll: 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
15024        llll: 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]',
15025    },
15026    calendar: {
15027        sameDay: '[Å iandien] LT',
15028        nextDay: '[Rytoj] LT',
15029        nextWeek: 'dddd LT',
15030        lastDay: '[Vakar] LT',
15031        lastWeek: '[Praėjusį] dddd LT',
15032        sameElse: 'L',
15033    },
15034    relativeTime: {
15035        future: 'po %s',
15036        past: 'prieš %s',
15037        s: translateSeconds,
15038        ss: translate,
15039        m: translateSingular,
15040        mm: translate,
15041        h: translateSingular,
15042        hh: translate,
15043        d: translateSingular,
15044        dd: translate,
15045        M: translateSingular,
15046        MM: translate,
15047        y: translateSingular,
15048        yy: translate,
15049    },
15050    dayOfMonthOrdinalParse: /\d{1,2}-oji/,
15051    ordinal: function (number) {
15052        return number + '-oji';
15053    },
15054    week: {
15055        dow: 1, // Monday is the first day of the week.
15056        doy: 4, // The week that contains Jan 4th is the first week of the year.
15057    },
15058}));
15059
15060
15061/***/ }),
15062/* 87 */
15063/***/ (function(module, __webpack_exports__, __webpack_require__) {
15064
15065"use strict";
15066Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
15067/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
15068//! moment.js locale configuration
15069//! locale : Latvian [lv]
15070//! author : Kristaps Karlsons : https://github.com/skakri
15071//! author : Jānis Elmeris : https://github.com/JanisE
15072
15073
15074
15075var units = {
15076    ss: 'sekundes_sekundēm_sekunde_sekundes'.split('_'),
15077    m: 'minūtes_minūtēm_minūte_minūtes'.split('_'),
15078    mm: 'minūtes_minūtēm_minūte_minūtes'.split('_'),
15079    h: 'stundas_stundām_stunda_stundas'.split('_'),
15080    hh: 'stundas_stundām_stunda_stundas'.split('_'),
15081    d: 'dienas_dienām_diena_dienas'.split('_'),
15082    dd: 'dienas_dienām_diena_dienas'.split('_'),
15083    M: 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),
15084    MM: 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'),
15085    y: 'gada_gadiem_gads_gadi'.split('_'),
15086    yy: 'gada_gadiem_gads_gadi'.split('_'),
15087};
15088/**
15089 * @param withoutSuffix boolean true = a length of time; false = before/after a period of time.
15090 */
15091function format(forms, number, withoutSuffix) {
15092    if (withoutSuffix) {
15093        // E.g. "21 minūte", "3 minūtes".
15094        return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3];
15095    } else {
15096        // E.g. "21 minūtes" as in "pēc 21 minūtes".
15097        // E.g. "3 minūtēm" as in "pēc 3 minūtēm".
15098        return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1];
15099    }
15100}
15101function relativeTimeWithPlural(number, withoutSuffix, key) {
15102    return number + ' ' + format(units[key], number, withoutSuffix);
15103}
15104function relativeTimeWithSingular(number, withoutSuffix, key) {
15105    return format(units[key], number, withoutSuffix);
15106}
15107function relativeSeconds(number, withoutSuffix) {
15108    return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm';
15109}
15110
15111/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('lv', {
15112    months: 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split(
15113        '_'
15114    ),
15115    monthsShort: 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),
15116    weekdays: 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split(
15117        '_'
15118    ),
15119    weekdaysShort: 'Sv_P_O_T_C_Pk_S'.split('_'),
15120    weekdaysMin: 'Sv_P_O_T_C_Pk_S'.split('_'),
15121    weekdaysParseExact: true,
15122    longDateFormat: {
15123        LT: 'HH:mm',
15124        LTS: 'HH:mm:ss',
15125        L: 'DD.MM.YYYY.',
15126        LL: 'YYYY. [gada] D. MMMM',
15127        LLL: 'YYYY. [gada] D. MMMM, HH:mm',
15128        LLLL: 'YYYY. [gada] D. MMMM, dddd, HH:mm',
15129    },
15130    calendar: {
15131        sameDay: '[Å odien pulksten] LT',
15132        nextDay: '[Rīt pulksten] LT',
15133        nextWeek: 'dddd [pulksten] LT',
15134        lastDay: '[Vakar pulksten] LT',
15135        lastWeek: '[Pagājušā] dddd [pulksten] LT',
15136        sameElse: 'L',
15137    },
15138    relativeTime: {
15139        future: 'pēc %s',
15140        past: 'pirms %s',
15141        s: relativeSeconds,
15142        ss: relativeTimeWithPlural,
15143        m: relativeTimeWithSingular,
15144        mm: relativeTimeWithPlural,
15145        h: relativeTimeWithSingular,
15146        hh: relativeTimeWithPlural,
15147        d: relativeTimeWithSingular,
15148        dd: relativeTimeWithPlural,
15149        M: relativeTimeWithSingular,
15150        MM: relativeTimeWithPlural,
15151        y: relativeTimeWithSingular,
15152        yy: relativeTimeWithPlural,
15153    },
15154    dayOfMonthOrdinalParse: /\d{1,2}\./,
15155    ordinal: '%d.',
15156    week: {
15157        dow: 1, // Monday is the first day of the week.
15158        doy: 4, // The week that contains Jan 4th is the first week of the year.
15159    },
15160}));
15161
15162
15163/***/ }),
15164/* 88 */
15165/***/ (function(module, __webpack_exports__, __webpack_require__) {
15166
15167"use strict";
15168Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
15169/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
15170//! moment.js locale configuration
15171//! locale : Montenegrin [me]
15172//! author : Miodrag Nikač <[email protected]> : https://github.com/miodragnikac
15173
15174
15175
15176var translator = {
15177    words: {
15178        //Different grammatical cases
15179        ss: ['sekund', 'sekunda', 'sekundi'],
15180        m: ['jedan minut', 'jednog minuta'],
15181        mm: ['minut', 'minuta', 'minuta'],
15182        h: ['jedan sat', 'jednog sata'],
15183        hh: ['sat', 'sata', 'sati'],
15184        dd: ['dan', 'dana', 'dana'],
15185        MM: ['mjesec', 'mjeseca', 'mjeseci'],
15186        yy: ['godina', 'godine', 'godina'],
15187    },
15188    correctGrammaticalCase: function (number, wordKey) {
15189        return number === 1
15190            ? wordKey[0]
15191            : number >= 2 && number <= 4
15192            ? wordKey[1]
15193            : wordKey[2];
15194    },
15195    translate: function (number, withoutSuffix, key) {
15196        var wordKey = translator.words[key];
15197        if (key.length === 1) {
15198            return withoutSuffix ? wordKey[0] : wordKey[1];
15199        } else {
15200            return (
15201                number +
15202                ' ' +
15203                translator.correctGrammaticalCase(number, wordKey)
15204            );
15205        }
15206    },
15207};
15208
15209/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('me', {
15210    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split(
15211        '_'
15212    ),
15213    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split(
15214        '_'
15215    ),
15216    monthsParseExact: true,
15217    weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split(
15218        '_'
15219    ),
15220    weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
15221    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),
15222    weekdaysParseExact: true,
15223    longDateFormat: {
15224        LT: 'H:mm',
15225        LTS: 'H:mm:ss',
15226        L: 'DD.MM.YYYY',
15227        LL: 'D. MMMM YYYY',
15228        LLL: 'D. MMMM YYYY H:mm',
15229        LLLL: 'dddd, D. MMMM YYYY H:mm',
15230    },
15231    calendar: {
15232        sameDay: '[danas u] LT',
15233        nextDay: '[sjutra u] LT',
15234
15235        nextWeek: function () {
15236            switch (this.day()) {
15237                case 0:
15238                    return '[u] [nedjelju] [u] LT';
15239                case 3:
15240                    return '[u] [srijedu] [u] LT';
15241                case 6:
15242                    return '[u] [subotu] [u] LT';
15243                case 1:
15244                case 2:
15245                case 4:
15246                case 5:
15247                    return '[u] dddd [u] LT';
15248            }
15249        },
15250        lastDay: '[juče u] LT',
15251        lastWeek: function () {
15252            var lastWeekDays = [
15253                '[prošle] [nedjelje] [u] LT',
15254                '[prošlog] [ponedjeljka] [u] LT',
15255                '[prošlog] [utorka] [u] LT',
15256                '[prošle] [srijede] [u] LT',
15257                '[prošlog] [četvrtka] [u] LT',
15258                '[prošlog] [petka] [u] LT',
15259                '[prošle] [subote] [u] LT',
15260            ];
15261            return lastWeekDays[this.day()];
15262        },
15263        sameElse: 'L',
15264    },
15265    relativeTime: {
15266        future: 'za %s',
15267        past: 'prije %s',
15268        s: 'nekoliko sekundi',
15269        ss: translator.translate,
15270        m: translator.translate,
15271        mm: translator.translate,
15272        h: translator.translate,
15273        hh: translator.translate,
15274        d: 'dan',
15275        dd: translator.translate,
15276        M: 'mjesec',
15277        MM: translator.translate,
15278        y: 'godinu',
15279        yy: translator.translate,
15280    },
15281    dayOfMonthOrdinalParse: /\d{1,2}\./,
15282    ordinal: '%d.',
15283    week: {
15284        dow: 1, // Monday is the first day of the week.
15285        doy: 7, // The week that contains Jan 7th is the first week of the year.
15286    },
15287}));
15288
15289
15290/***/ }),
15291/* 89 */
15292/***/ (function(module, __webpack_exports__, __webpack_require__) {
15293
15294"use strict";
15295Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
15296/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
15297//! moment.js locale configuration
15298//! locale : Maori [mi]
15299//! author : John Corrigan <[email protected]> : https://github.com/johnideal
15300
15301
15302
15303/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('mi', {
15304    months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split(
15305        '_'
15306    ),
15307    monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split(
15308        '_'
15309    ),
15310    monthsRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,
15311    monthsStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,
15312    monthsShortRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,
15313    monthsShortStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i,
15314    weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'),
15315    weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),
15316    weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'),
15317    longDateFormat: {
15318        LT: 'HH:mm',
15319        LTS: 'HH:mm:ss',
15320        L: 'DD/MM/YYYY',
15321        LL: 'D MMMM YYYY',
15322        LLL: 'D MMMM YYYY [i] HH:mm',
15323        LLLL: 'dddd, D MMMM YYYY [i] HH:mm',
15324    },
15325    calendar: {
15326        sameDay: '[i teie mahana, i] LT',
15327        nextDay: '[apopo i] LT',
15328        nextWeek: 'dddd [i] LT',
15329        lastDay: '[inanahi i] LT',
15330        lastWeek: 'dddd [whakamutunga i] LT',
15331        sameElse: 'L',
15332    },
15333    relativeTime: {
15334        future: 'i roto i %s',
15335        past: '%s i mua',
15336        s: 'te hēkona ruarua',
15337        ss: '%d hēkona',
15338        m: 'he meneti',
15339        mm: '%d meneti',
15340        h: 'te haora',
15341        hh: '%d haora',
15342        d: 'he ra',
15343        dd: '%d ra',
15344        M: 'he marama',
15345        MM: '%d marama',
15346        y: 'he tau',
15347        yy: '%d tau',
15348    },
15349    dayOfMonthOrdinalParse: /\d{1,2}º/,
15350    ordinal: '%dº',
15351    week: {
15352        dow: 1, // Monday is the first day of the week.
15353        doy: 4, // The week that contains Jan 4th is the first week of the year.
15354    },
15355}));
15356
15357
15358/***/ }),
15359/* 90 */
15360/***/ (function(module, __webpack_exports__, __webpack_require__) {
15361
15362"use strict";
15363Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
15364/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
15365//! moment.js locale configuration
15366//! locale : Macedonian [mk]
15367//! author : Borislav Mickov : https://github.com/B0k0
15368//! author : Sashko Todorov : https://github.com/bkyceh
15369
15370
15371/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('mk', {
15372    months: 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split(
15373        '_'
15374    ),
15375    monthsShort: 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),
15376    weekdays: 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split(
15377        '_'
15378    ),
15379    weekdaysShort: 'нед_пон_вто_сре_чет_пет_саб'.split('_'),
15380    weekdaysMin: 'нe_пo_вт_ср_че_пе_сa'.split('_'),
15381    longDateFormat: {
15382        LT: 'H:mm',
15383        LTS: 'H:mm:ss',
15384        L: 'D.MM.YYYY',
15385        LL: 'D MMMM YYYY',
15386        LLL: 'D MMMM YYYY H:mm',
15387        LLLL: 'dddd, D MMMM YYYY H:mm',
15388    },
15389    calendar: {
15390        sameDay: '[Денес во] LT',
15391        nextDay: '[Утре во] LT',
15392        nextWeek: '[Во] dddd [во] LT',
15393        lastDay: '[Вчера во] LT',
15394        lastWeek: function () {
15395            switch (this.day()) {
15396                case 0:
15397                case 3:
15398                case 6:
15399                    return '[Изминатата] dddd [во] LT';
15400                case 1:
15401                case 2:
15402                case 4:
15403                case 5:
15404                    return '[Изминатиот] dddd [во] LT';
15405            }
15406        },
15407        sameElse: 'L',
15408    },
15409    relativeTime: {
15410        future: 'за %s',
15411        past: 'пред %s',
15412        s: 'неколку секунди',
15413        ss: '%d секунди',
15414        m: 'една минута',
15415        mm: '%d минути',
15416        h: 'еден час',
15417        hh: '%d часа',
15418        d: 'еден ден',
15419        dd: '%d дена',
15420        M: 'еден месец',
15421        MM: '%d месеци',
15422        y: 'една година',
15423        yy: '%d години',
15424    },
15425    dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
15426    ordinal: function (number) {
15427        var lastDigit = number % 10,
15428            last2Digits = number % 100;
15429        if (number === 0) {
15430            return number + '-ев';
15431        } else if (last2Digits === 0) {
15432            return number + '-ен';
15433        } else if (last2Digits > 10 && last2Digits < 20) {
15434            return number + '-ти';
15435        } else if (lastDigit === 1) {
15436            return number + '-ви';
15437        } else if (lastDigit === 2) {
15438            return number + '-ри';
15439        } else if (lastDigit === 7 || lastDigit === 8) {
15440            return number + '-ми';
15441        } else {
15442            return number + '-ти';
15443        }
15444    },
15445    week: {
15446        dow: 1, // Monday is the first day of the week.
15447        doy: 7, // The week that contains Jan 7th is the first week of the year.
15448    },
15449}));
15450
15451
15452/***/ }),
15453/* 91 */
15454/***/ (function(module, __webpack_exports__, __webpack_require__) {
15455
15456"use strict";
15457Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
15458/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
15459//! moment.js locale configuration
15460//! locale : Malayalam [ml]
15461//! author : Floyd Pink : https://github.com/floydpink
15462
15463
15464
15465/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ml', {
15466    months: 'ജനുവരി_ഫെബ്രുവരി_മാർച്ചà
vendor: 5,857 bytes, lines 15466-15612
15466µ_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split(
15467        '_'
15468    ),
15469    monthsShort: 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split(
15470        '_'
15471    ),
15472    monthsParseExact: true,
15473    weekdays: 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split(
15474        '_'
15475    ),
15476    weekdaysShort: 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),
15477    weekdaysMin: 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),
15478    longDateFormat: {
15479        LT: 'A h:mm -നു',
15480        LTS: 'A h:mm:ss -നു',
15481        L: 'DD/MM/YYYY',
15482        LL: 'D MMMM YYYY',
15483        LLL: 'D MMMM YYYY, A h:mm -നു',
15484        LLLL: 'dddd, D MMMM YYYY, A h:mm -നു',
15485    },
15486    calendar: {
15487        sameDay: '[ഇന്ന്] LT',
15488        nextDay: '[നാളെ] LT',
15489        nextWeek: 'dddd, LT',
15490        lastDay: '[ഇന്നലെ] LT',
15491        lastWeek: '[കഴിഞ്ഞ] dddd, LT',
15492        sameElse: 'L',
15493    },
15494    relativeTime: {
15495        future: '%s കഴിഞ്ഞ്',
15496        past: '%s മുൻപ്',
15497        s: 'അൽപ നിമിഷങ്ങൾ',
15498        ss: '%d സെക്കൻഡ്',
15499        m: 'ഒരു മിനിറ്റ്',
15500        mm: '%d മിനിറ്റ്',
15501        h: 'ഒരു മണിക്കൂർ',
15502        hh: '%d മണിക്കൂർ',
15503        d: 'ഒരു ദിവസം',
15504        dd: '%d ദിവസം',
15505        M: 'ഒരു മാസം',
15506        MM: '%d മാസം',
15507        y: 'ഒരു വർഷം',
15508        yy: '%d വർഷം',
15509    },
15510    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,
15511    meridiemHour: function (hour, meridiem) {
15512        if (hour === 12) {
15513            hour = 0;
15514        }
15515        if (
15516            (meridiem === 'രാത്രി' && hour >= 4) ||
15517            meridiem === 'ഉച്ച കഴിഞ്ഞ്' ||
15518            meridiem === 'വൈകുന്നേരം'
15519        ) {
15520            return hour + 12;
15521        } else {
15522            return hour;
15523        }
15524    },
15525    meridiem: function (hour, minute, isLower) {
15526        if (hour < 4) {
15527            return 'രാത്രി';
15528        } else if (hour < 12) {
15529            return 'രാവിലെ';
15530        } else if (hour < 17) {
15531            return 'ഉച്ച കഴിഞ്ഞ്';
15532        } else if (hour < 20) {
15533            return 'വൈകുന്നേരം';
15534        } else {
15535            return 'രാത്രി';
15536        }
15537    },
15538}));
15539
15540
15541/***/ }),
15542/* 92 */
15543/***/ (function(module, __webpack_exports__, __webpack_require__) {
15544
15545"use strict";
15546Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
15547/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
15548//! moment.js locale configuration
15549//! locale : Mongolian [mn]
15550//! author : Javkhlantugs Nyamdorj : https://github.com/javkhaanj7
15551
15552
15553
15554function translate(number, withoutSuffix, key, isFuture) {
15555    switch (key) {
15556        case 's':
15557            return withoutSuffix ? 'хэдхэн секунд' : 'хэдхэн секундын';
15558        case 'ss':
15559            return number + (withoutSuffix ? ' секунд' : ' секундын');
15560        case 'm':
15561        case 'mm':
15562            return number + (withoutSuffix ? ' минут' : ' минутын');
15563        case 'h':
15564        case 'hh':
15565            return number + (withoutSuffix ? ' цаг' : ' цагийн');
15566        case 'd':
15567        case 'dd':
15568            return number + (withoutSuffix ? ' өдөр' : ' өдрийн');
15569        case 'M':
15570        case 'MM':
15571            return number + (withoutSuffix ? ' сар' : ' сарын');
15572        case 'y':
15573        case 'yy':
15574            return number + (withoutSuffix ? ' жил' : ' жилийн');
15575        default:
15576            return number;
15577    }
15578}
15579
15580/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('mn', {
15581    months: 'Нэгдүгээр сар_Хоёрдугаар сар_Гуравдугаар сар_Дөрөвдүгээр сар_Тавдугаар сар_Зургадугаар сар_Долдугаар сар_Наймдугаар сар_Есдүгээр сар_Аравдугаар сар_Арван нэгдүгээр сар_Арван хоёрдугаар сар'.split(
15582        '_'
15583    ),
15584    monthsShort: '1 сар_2 сар_3 сар_4 сар_5 сар_6 сар_7 сар_8 сар_9 сар_10 сар_11 сар_12 сар'.split(
15585        '_'
15586    ),
15587    monthsParseExact: true,
15588    weekdays: 'Ням_Даваа_Мягмар_Лхагва_Пүрэв_Баасан_Бямба'.split('_'),
15589    weekdaysShort: 'Ням_Дав_Мяг_Лха_Пүр_Баа_Бям'.split('_'),
15590    weekdaysMin: 'Ня_Да_Мя_Лх_Пү_Ба_Бя'.split('_'),
15591    weekdaysParseExact: true,
15592    longDateFormat: {
15593        LT: 'HH:mm',
15594        LTS: 'HH:mm:ss',
15595        L: 'YYYY-MM-DD',
15596        LL: 'YYYY оны MMMMын D',
15597        LLL: 'YYYY оны MMMMын D HH:mm',
15598        LLLL: 'dddd, YYYY оны MMMMын D HH:mm',
15599    },
15600    meridiemParse: /ҮӨ|ҮХ/i,
15601    isPM: function (input) {
15602        return input === 'ҮХ';
15603    },
15604    meridiem: function (hour, minute, isLower) {
15605        if (hour < 12) {
15606            return 'Ò®Ó¨';
15607        } else {
15608            return 'ҮХ';
15609        }
15610    },
15611    calendar: {
15612        sameDay: '[Өнөөдөр] LT',
15613        nextDay: '[Маргааш] LT',
15614        nextWeek: '[Ирэх] dddd LT',
15615        lastDay: '[Өчигдөр] LT',
15616        lastWeek: '[Өнгөрсөн] dddd LT',
15617        sameElse: 'L',
15618    },
15619    relativeTime: {
15620        future: '%s дараа',
15621        past: '%s өмнө',
15622        s: translate,
15623        ss: translate,
15624        m: translate,
15625        mm: translate,
15626        h: translate,
15627        hh: translate,
15628        d: translate,
15629        dd: translate,
15630        M: translate,
15631        MM: translate,
15632        y: translate,
15633        yy: translate,
15634    },
15635    dayOfMonthOrdinalParse: /\d{1,2} өдөр/,
15636    ordinal: function (number, period) {
15637        switch (period) {
15638            case 'd':
15639            case 'D':
15640            case 'DDD':
15641                return number + ' өдөр';
15642            default:
15643                return number;
15644        }
15645    },
15646}));
15647
15648
15649/***/ }),
15650/* 93 */
15651/***/ (function(module, __webpack_exports__, __webpack_require__) {
15652
15653"use strict";
15654Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
15655/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
15656//! moment.js locale configuration
15657//! locale : Marathi [mr]
15658//! author : Harshad Kale : https://github.com/kalehv
15659//! author : Vivek Athalye : https://github.com/vnathalye
15660
15661
15662
15663var symbolMap = {
15664        1: '१',
15665        2: '२',
15666        3: '३',
15667        4: '४',
15668        5: '५',
15669        6: '६',
15670        7: '७',
15671        8: '८',
15672        9: '९',
15673        0: '०',
15674    },
15675    numberMap = {
15676        '१': '1',
15677        '२': '2',
15678        '३': '3',
15679        '४': '4',
15680        '५': '5',
15681        '६': '6',
15682        '७': '7',
15683        '८': '8',
15684        '९': '9',
15685        '०': '0',
15686    };
15687
15688function relativeTimeMr(number, withoutSuffix, string, isFuture) {
15689    var output = '';
15690    if (withoutSuffix) {
15691        switch (string) {
15692            case 's':
15693                output = 'काही सेकंद';
15694                break;
15695            case 'ss':
15696                output = '%d सेकंद';
15697                break;
15698            case 'm':
15699                output = 'एक मिनिट';
15700                break;
15701            case 'mm':
15702                output = '%d मिनिटे';
15703                break;
15704            case 'h':
15705                output = 'एक तास';
15706                break;
15707            case 'hh':
15708                output = '%d तास';
15709                break;
15710            case 'd':
15711                output = 'एक दिवस';
15712                break;
15713            case 'dd':
15714                output = '%d दिवस';
15715                break;
15716            case 'M':
15717                output = 'एक महिना';
15718                break;
15719            case 'MM':
15720                output = '%d महिने';
15721                break;
15722            case 'y':
15723                output = 'एक वर्ष';
15724                break;
15725            case 'yy':
15726                output = '%d वर्षे';
15727                break;
15728        }
15729    } else {
15730        switch (string) {
15731            case 's':
15732                output = 'काही सेकंदां';
15733                break;
15734            case 'ss':
15735                output = '%d सेकंदां';
15736                break;
15737            case 'm':
15738                output = 'एका मिनिटा';
15739                break;
15740            case 'mm':
15741                output = '%d मिनिटां';
15742                break;
15743            case 'h':
15744                output = 'एका तासा';
15745                break;
15746            case 'hh':
15747                output = '%d तासां';
15748                break;
15749            case 'd':
15750                output = 'एका दिवसा';
15751                break;
15752            case 'dd':
15753                output = '%d दिवसां';
15754                break;
15755            case 'M':
15756                output = 'एका महिन्या';
15757                break;
15758            case 'MM':
15759                output = '%d महिन्यां';
15760                break;
15761            case 'y':
15762                output = 'एका वर्षा';
15763                break;
15764            case 'yy':
15765                output = '%d वर्षां';
15766                break;
15767        }
15768    }
15769    return output.replace(/%d/i, number);
15770}
15771
15772/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('mr', {
15773    months: 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split(
15774        '_'
15775    ),
15776    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split(
15777        '_'
15778    ),
15779    monthsParseExact: true,
15780    weekdays: 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
15781    weekdaysShort: 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),
15782    weekdaysMin: 'र_सो_मं_बु_गु_शु_श'.split('_'),
15783    longDateFormat: {
15784        LT: 'A h:mm वाजता',
15785        LTS: 'A h:mm:ss वाजता',
15786        L: 'DD/MM/YYYY',
15787        LL: 'D MMMM YYYY',
15788        LLL: 'D MMMM YYYY, A h:mm वाजता',
15789        LLLL: 'dddd, D MMMM YYYY, A h:mm वाजता',
15790    },
15791    calendar: {
15792        sameDay: '[आज] LT',
15793        nextDay: '[उद्या] LT',
15794        nextWeek: 'dddd, LT',
15795        lastDay: '[काल] LT',
15796        lastWeek: '[मागील] dddd, LT',
15797        sameElse: 'L',
15798    },
15799    relativeTime: {
15800        future: '%sमध्ये',
15801        past: '%sपूर्वी',
15802        s: relativeTimeMr,
15803        ss: relativeTimeMr,
15804        m: relativeTimeMr,
15805        mm: relativeTimeMr,
15806        h: relativeTimeMr,
15807        hh: relativeTimeMr,
15808        d: relativeTimeMr,
15809        dd: relativeTimeMr,
15810        M: relativeTimeMr,
15811        MM: relativeTimeMr,
15812        y: relativeTimeMr,
15813        yy: relativeTimeMr,
15814    },
15815    preparse: function (string) {
15816        return string.replace(/[१२३४५६७८९०]/g, function (match) {
15817            return numberMap[match];
15818        });
15819    },
15820    postformat: function (string) {
15821        return string.replace(/\d/g, function (match) {
15822            return symbolMap[match];
15823        });
15824    },
15825    meridiemParse: /पहाटे|सकाळी|दुपारी|सायंकाळी|रात्री/,
15826    meridiemHour: function (hour, meridiem) {
15827        if (hour === 12) {
15828            hour = 0;
15829        }
15830        if (meridiem === 'पहाटे' || meridiem === 'सकाळी') {
15831            return hour;
15832        } else if (
15833            meridiem === 'दुपारी' ||
15834            meridiem === 'सायंकाळी' ||
15835            meridiem === 'रात्री'
15836        ) {
15837            return hour >= 12 ? hour : hour + 12;
15838        }
15839    },
15840    meridiem: function (hour, minute, isLower) {
15841        if (hour >= 0 && hour < 6) {
15842            return 'पहाटे';
15843        } else if (hour < 12) {
15844            return 'सकाळी';
15845        } else if (hour < 17) {
15846            return 'दुपारी';
15847        } else if (hour < 20) {
15848            return 'सायंकाळी';
15849        } else {
15850            return 'रात्री';
15851        }
15852    },
15853    week: {
15854        dow: 0, // Sunday is the first day of the week.
15855        doy: 6, // The week that contains Jan 6th is the first week of the year.
15856    },
15857}));
15858
15859
15860/***/ }),
15861/* 94 */
15862/***/ (function(module, __webpack_exports__, __webpack_require__) {
15863
15864"use strict";
15865Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
15866/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
15867//! moment.js locale configuration
15868//! locale : Malay [ms]
15869//! author : Weldan Jamili : https://github.com/weldan
15870
15871
15872
15873/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ms', {
15874    months: 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split(
15875        '_'
15876    ),
15877    monthsShort: 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
15878    weekdays: 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
15879    weekdaysShort: 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
15880    weekdaysMin: 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
15881    longDateFormat: {
15882        LT: 'HH.mm',
15883        LTS: 'HH.mm.ss',
15884        L: 'DD/MM/YYYY',
15885        LL: 'D MMMM YYYY',
15886        LLL: 'D MMMM YYYY [pukul] HH.mm',
15887        LLLL: 'dddd, D MMMM YYYY [pukul] HH.mm',
15888    },
15889    meridiemParse: /pagi|tengahari|petang|malam/,
15890    meridiemHour: function (hour, meridiem) {
15891        if (hour === 12) {
15892            hour = 0;
15893        }
15894        if (meridiem === 'pagi') {
15895            return hour;
15896        } else if (meridiem === 'tengahari') {
15897            return hour >= 11 ? hour : hour + 12;
15898        } else if (meridiem === 'petang' || meridiem === 'malam') {
15899            return hour + 12;
15900        }
15901    },
15902    meridiem: function (hours, minutes, isLower) {
15903        if (hours < 11) {
15904            return 'pagi';
15905        } else if (hours < 15) {
15906            return 'tengahari';
15907        } else if (hours < 19) {
15908            return 'petang';
15909        } else {
15910            return 'malam';
15911        }
15912    },
15913    calendar: {
15914        sameDay: '[Hari ini pukul] LT',
15915        nextDay: '[Esok pukul] LT',
15916        nextWeek: 'dddd [pukul] LT',
15917        lastDay: '[Kelmarin pukul] LT',
15918        lastWeek: 'dddd [lepas pukul] LT',
15919        sameElse: 'L',
15920    },
15921    relativeTime: {
15922        future: 'dalam %s',
15923        past: '%s yang lepas',
15924        s: 'beberapa saat',
15925        ss: '%d saat',
15926        m: 'seminit',
15927        mm: '%d minit',
15928        h: 'sejam',
15929        hh: '%d jam',
15930        d: 'sehari',
15931        dd: '%d hari',
15932        M: 'sebulan',
15933        MM: '%d bulan',
15934        y: 'setahun',
15935        yy: '%d tahun',
15936    },
15937    week: {
15938        dow: 1, // Monday is the first day of the week.
15939        doy: 7, // The week that contains Jan 7th is the first week of the year.
15940    },
15941}));
15942
15943
15944/***/ }),
15945/* 95 */
15946/***/ (function(module, __webpack_exports__, __webpack_require__) {
15947
15948"use strict";
15949Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
15950/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
15951//! moment.js locale configuration
15952//! locale : Malay [ms-my]
15953//! note : DEPRECATED, the correct one is [ms]
15954//! author : Weldan Jamili : https://github.com/weldan
15955
15956
15957
15958/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ms-my', {
15959    months: 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split(
15960        '_'
15961    ),
15962    monthsShort: 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
15963    weekdays: 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
15964    weekdaysShort: 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
15965    weekdaysMin: 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
15966    longDateFormat: {
15967        LT: 'HH.mm',
15968        LTS: 'HH.mm.ss',
15969        L: 'DD/MM/YYYY',
15970        LL: 'D MMMM YYYY',
15971        LLL: 'D MMMM YYYY [pukul] HH.mm',
15972        LLLL: 'dddd, D MMMM YYYY [pukul] HH.mm',
15973    },
15974    meridiemParse: /pagi|tengahari|petang|malam/,
15975    meridiemHour: function (hour, meridiem) {
15976        if (hour === 12) {
15977            hour = 0;
15978        }
15979        if (meridiem === 'pagi') {
15980            return hour;
15981        } else if (meridiem === 'tengahari') {
15982            return hour >= 11 ? hour : hour + 12;
15983        } else if (meridiem === 'petang' || meridiem === 'malam') {
15984            return hour + 12;
15985        }
15986    },
15987    meridiem: function (hours, minutes, isLower) {
15988        if (hours < 11) {
15989            return 'pagi';
15990        } else if (hours < 15) {
15991            return 'tengahari';
15992        } else if (hours < 19) {
15993            return 'petang';
15994        } else {
15995            return 'malam';
15996        }
15997    },
15998    calendar: {
15999        sameDay: '[Hari ini pukul] LT',
16000        nextDay: '[Esok pukul] LT',
16001        nextWeek: 'dddd [pukul] LT',
16002        lastDay: '[Kelmarin pukul] LT',
16003        lastWeek: 'dddd [lepas pukul] LT',
16004        sameElse: 'L',
16005    },
16006    relativeTime: {
16007        future: 'dalam %s',
16008        past: '%s yang lepas',
16009        s: 'beberapa saat',
16010        ss: '%d saat',
16011        m: 'seminit',
16012        mm: '%d minit',
16013        h: 'sejam',
16014        hh: '%d jam',
16015        d: 'sehari',
16016        dd: '%d hari',
16017        M: 'sebulan',
16018        MM: '%d bulan',
16019        y: 'setahun',
16020        yy: '%d tahun',
16021    },
16022    week: {
16023        dow: 1, // Monday is the first day of the week.
16024        doy: 7, // The week that contains Jan 7th is the first week of the year.
16025    },
16026}));
16027
16028
16029/***/ }),
16030/* 96 */
16031/***/ (function(module, __webpack_exports__, __webpack_require__) {
16032
16033"use strict";
16034Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
16035/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
16036//! moment.js locale configuration
16037//! locale : Maltese (Malta) [mt]
16038//! author : Alessandro Maruccia : https://github.com/alesma
16039
16040
16041
16042/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('mt', {
16043    months: 'Jannar_Frar_Marzu_April_Mejju_Ġunju_Lulju_Awwissu_Settembru_Ottubru_Novembru_Diċembru'.split(
16044        '_'
16045    ),
16046    monthsShort: 'Jan_Fra_Mar_Apr_Mej_Ġun_Lul_Aww_Set_Ott_Nov_Diċ'.split('_'),
16047    weekdays: 'Il-Ħadd_It-Tnejn_It-Tlieta_L-Erbgħa_Il-Ħamis_Il-Ġimgħa_Is-Sibt'.split(
16048        '_'
16049    ),
16050    weekdaysShort: 'Ħad_Tne_Tli_Erb_Ħam_Ġim_Sib'.split('_'),
16051    weekdaysMin: 'Ħa_Tn_Tl_Er_Ħa_Ġi_Si'.split('_'),
16052    longDateFormat: {
16053        LT: 'HH:mm',
16054        LTS: 'HH:mm:ss',
16055        L: 'DD/MM/YYYY',
16056        LL: 'D MMMM YYYY',
16057        LLL: 'D MMMM YYYY HH:mm',
16058        LLLL: 'dddd, D MMMM YYYY HH:mm',
16059    },
16060    calendar: {
16061        sameDay: '[Illum fil-]LT',
16062        nextDay: '[Għada fil-]LT',
16063        nextWeek: 'dddd [fil-]LT',
16064        lastDay: '[Il-bieraħ fil-]LT',
16065        lastWeek: 'dddd [li għadda] [fil-]LT',
16066        sameElse: 'L',
16067    },
16068    relativeTime: {
16069        future: 'f’ %s',
16070        past: '%s ilu',
16071        s: 'ftit sekondi',
16072        ss: '%d sekondi',
16073        m: 'minuta',
16074        mm: '%d minuti',
16075        h: 'siegħa',
16076        hh: '%d siegħat',
16077        d: 'ġurnata',
16078        dd: '%d ġranet',
16079        M: 'xahar',
16080        MM: '%d xhur',
16081        y: 'sena',
16082        yy: '%d sni',
16083    },
16084    dayOfMonthOrdinalParse: /\d{1,2}º/,
16085    ordinal: '%dº',
16086    week: {
16087        dow: 1, // Monday is the first day of the week.
16088        doy: 4, // The week that contains Jan 4th is the first week of the year.
16089    },
16090}));
16091
16092
16093/***/ }),
16094/* 97 */
16095/***/ (function(module, __webpack_exports__, __webpack_require__) {
16096
16097"use strict";
16098Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
16099/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
16100//! moment.js locale configuration
16101//! locale : Burmese [my]
16102//! author : Squar team, mysquar.com
16103//! author : David Rossellat : https://github.com/gholadr
16104//! author : Tin Aung Lin : https://github.com/thanyawzinmin
16105
16106
16107
16108var symbolMap = {
16109        1: '၁',
16110        2: '၂',
16111        3: '၃',
16112        4: '၄',
16113        5: '၅',
16114        6: '၆',
16115        7: '၇',
16116        8: '၈',
16117        9: '၉',
16118        0: '၀',
16119    },
16120    numberMap = {
16121        '၁': '1',
16122        '၂': '2',
16123        '၃': '3',
16124        '၄': '4',
16125        '၅': '5',
16126        '၆': '6',
16127        '၇': '7',
16128        '၈': '8',
16129        '၉': '9',
16130        '၀': '0',
16131    };
16132
16133/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('my', {
16134    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split(
16135        '_'
16136    ),
16137    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),
16138    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split(
16139        '_'
16140    ),
16141    weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),
16142    weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),
16143
16144    longDateFormat: {
16145        LT: 'HH:mm',
16146        LTS: 'HH:mm:ss',
16147        L: 'DD/MM/YYYY',
16148        LL: 'D MMMM YYYY',
16149        LLL: 'D MMMM YYYY HH:mm',
16150        LLLL: 'dddd D MMMM YYYY HH:mm',
16151    },
16152    calendar: {
16153        sameDay: '[ယနေ.] LT [မှာ]',
16154        nextDay: '[မနက်ဖြန်] LT [မှာ]',
16155        nextWeek: 'dddd LT [မှာ]',
16156        lastDay: '[မနေ.က] LT [မှာ]',
16157        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',
16158        sameElse: 'L',
16159    },
16160    relativeTime: {
16161        future: 'လာမည့် %s မှာ',
16162        past: 'လွန်ခဲ့သော %s က',
16163        s: 'စက္ကန်.အနည်းငယ်',
16164        ss: '%d စက္ကန့်',
16165        m: 'တစ်မိနစ်',
16166        mm: '%d မိနစ်',
16167        h: 'တစ်နာရီ',
16168        hh: '%d နာရီ',
16169        d: 'တစ်ရက်',
16170        dd: '%d ရက်',
16171        M: 'တစ်လ',
16172        MM: '%d လ',
16173        y: 'တစ်နှစ်',
16174        yy: '%d နှစ်',
16175    },
16176    preparse: function (string) {
16177        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {
16178            return numberMap[match];
16179        });
16180    },
16181    postformat: function (string) {
16182        return string.replace(/\d/g, function (match) {
16183            return symbolMap[match];
16184        });
16185    },
16186    week: {
16187        dow: 1, // Monday is the first day of the week.
16188        doy: 4, // The week that contains Jan 4th is the first week of the year.
16189    },
16190}));
16191
16192
16193/***/ }),
16194/* 98 */
16195/***/ (function(module, __webpack_exports__, __webpack_require__) {
16196
16197"use strict";
16198Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
16199/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
16200//! moment.js locale configuration
16201//! locale : Norwegian Bokmål [nb]
16202//! authors : Espen Hovlandsdal : https://github.com/rexxars
16203//!           Sigurd Gartmann : https://github.com/sigurdga
16204//!           Stephen Ramthun : https://github.com/stephenramthun
16205
16206
16207
16208/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('nb', {
16209    months: 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split(
16210        '_'
16211    ),
16212    monthsShort: 'jan._feb._mars_apr._mai_juni_juli_aug._sep._okt._nov._des.'.split(
16213        '_'
16214    ),
16215    monthsParseExact: true,
16216    weekdays: 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
16217    weekdaysShort: 'sø._ma._ti._on._to._fr._lø.'.split('_'),
16218    weekdaysMin: 'sø_ma_ti_on_to_fr_lø'.split('_'),
16219    weekdaysParseExact: true,
16220    longDateFormat: {
16221        LT: 'HH:mm',
16222        LTS: 'HH:mm:ss',
16223        L: 'DD.MM.YYYY',
16224        LL: 'D. MMMM YYYY',
16225        LLL: 'D. MMMM YYYY [kl.] HH:mm',
16226        LLLL: 'dddd D. MMMM YYYY [kl.] HH:mm',
16227    },
16228    calendar: {
16229        sameDay: '[i dag kl.] LT',
16230        nextDay: '[i morgen kl.] LT',
16231        nextWeek: 'dddd [kl.] LT',
16232        lastDay: '[i går kl.] LT',
16233        lastWeek: '[forrige] dddd [kl.] LT',
16234        sameElse: 'L',
16235    },
16236    relativeTime: {
16237        future: 'om %s',
16238        past: '%s siden',
16239        s: 'noen sekunder',
16240        ss: '%d sekunder',
16241        m: 'ett minutt',
16242        mm: '%d minutter',
16243        h: 'en time',
16244        hh: '%d timer',
16245        d: 'en dag',
16246        dd: '%d dager',
16247        w: 'en uke',
16248        ww: '%d uker',
16249        M: 'en måned',
16250        MM: '%d måneder',
16251        y: 'ett år',
16252        yy: '%d år',
16253    },
16254    dayOfMonthOrdinalParse: /\d{1,2}\./,
16255    ordinal: '%d.',
16256    week: {
16257        dow: 1, // Monday is the first day of the week.
16258        doy: 4, // The week that contains Jan 4th is the first week of the year.
16259    },
16260}));
16261
16262
16263/***/ }),
16264/* 99 */
16265/***/ (function(module, __webpack_exports__, __webpack_require__) {
16266
16267"use strict";
16268Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
16269/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
16270//! moment.js locale configuration
16271//! locale : Nepalese [ne]
16272//! author : suvash : https://github.com/suvash
16273
16274
16275
16276var symbolMap = {
16277        1: '१',
16278        2: '२',
16279        3: '३',
16280        4: '४',
16281        5: '५',
16282        6: '६',
16283        7: '७',
16284        8: '८',
16285        9: '९',
16286        0: '०',
16287    },
16288    numberMap = {
16289        '१': '1',
16290        '२': '2',
16291        '३': '3',
16292        '४': '4',
16293        '५': '5',
16294        '६': '6',
16295        '७': '7',
16296        '८': '8',
16297        '९': '9',
16298        '०': '0',
16299    };
16300
16301/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ne', {
16302    months: 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split(
16303        '_'
16304    ),
16305    monthsShort: 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split(
16306        '_'
16307    ),
16308    monthsParseExact: true,
16309    weekdays: 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split(
16310        '_'
16311    ),
16312    weekdaysShort: 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),
16313    weekdaysMin: 'आ._सो._मं._बु._बि._शु._श.'.split('_'),
16314    weekdaysParseExact: true,
16315    longDateFormat: {
16316        LT: 'Aको h:mm बजे',
16317        LTS: 'Aको h:mm:ss बजे',
16318        L: 'DD/MM/YYYY',
16319        LL: 'D MMMM YYYY',
16320        LLL: 'D MMMM YYYY, Aको h:mm बजे',
16321        LLLL: 'dddd, D MMMM YYYY, Aको h:mm बजे',
16322    },
16323    preparse: function (string) {
16324        return string.replace(/[१२३४५६७८९०]/g, function (match) {
16325            return numberMap[match];
16326        });
16327    },
16328    postformat: function (string) {
16329        return string.replace(/\d/g, function (match) {
16330            return symbolMap[match];
16331        });
16332    },
vendor: 4,974 bytes, lines 16333-16487
16333    meridiemParse: /राति|बिहान|दिउँसो|साँझ/,
16334    meridiemHour: function (hour, meridiem) {
16335        if (hour === 12) {
16336            hour = 0;
16337        }
16338        if (meridiem === 'राति') {
16339            return hour < 4 ? hour : hour + 12;
16340        } else if (meridiem === 'बिहान') {
16341            return hour;
16342        } else if (meridiem === 'दिउँसो') {
16343            return hour >= 10 ? hour : hour + 12;
16344        } else if (meridiem === 'साँझ') {
16345            return hour + 12;
16346        }
16347    },
16348    meridiem: function (hour, minute, isLower) {
16349        if (hour < 3) {
16350            return 'राति';
16351        } else if (hour < 12) {
16352            return 'बिहान';
16353        } else if (hour < 16) {
16354            return 'दिउँसो';
16355        } else if (hour < 20) {
16356            return 'साँझ';
16357        } else {
16358            return 'राति';
16359        }
16360    },
16361    calendar: {
16362        sameDay: '[आज] LT',
16363        nextDay: '[भोलि] LT',
16364        nextWeek: '[आउँदो] dddd[,] LT',
16365        lastDay: '[हिजो] LT',
16366        lastWeek: '[गएको] dddd[,] LT',
16367        sameElse: 'L',
16368    },
16369    relativeTime: {
16370        future: '%sमा',
16371        past: '%s अगाडि',
16372        s: 'केही क्षण',
16373        ss: '%d सेकेण्ड',
16374        m: 'एक मिनेट',
16375        mm: '%d मिनेट',
16376        h: 'एक घण्टा',
16377        hh: '%d घण्टा',
16378        d: 'एक दिन',
16379        dd: '%d दिन',
16380        M: 'एक महिना',
16381        MM: '%d महिना',
16382        y: 'एक बर्ष',
16383        yy: '%d बर्ष',
16384    },
16385    week: {
16386        dow: 0, // Sunday is the first day of the week.
16387        doy: 6, // The week that contains Jan 6th is the first week of the year.
16388    },
16389}));
16390
16391
16392/***/ }),
16393/* 100 */
16394/***/ (function(module, __webpack_exports__, __webpack_require__) {
16395
16396"use strict";
16397Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
16398/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
16399//! moment.js locale configuration
16400//! locale : Dutch [nl]
16401//! author : Joris Röling : https://github.com/jorisroling
16402//! author : Jacob Middag : https://github.com/middagj
16403
16404
16405
16406var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split(
16407        '_'
16408    ),
16409    monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split(
16410        '_'
16411    ),
16412    monthsParse = [
16413        /^jan/i,
16414        /^feb/i,
16415        /^maart|mrt.?$/i,
16416        /^apr/i,
16417        /^mei$/i,
16418        /^jun[i.]?$/i,
16419        /^jul[i.]?$/i,
16420        /^aug/i,
16421        /^sep/i,
16422        /^okt/i,
16423        /^nov/i,
16424        /^dec/i,
16425    ],
16426    monthsRegex = /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;
16427
16428/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('nl', {
16429    months: 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split(
16430        '_'
16431    ),
16432    monthsShort: function (m, format) {
16433        if (!m) {
16434            return monthsShortWithDots;
16435        } else if (/-MMM-/.test(format)) {
16436            return monthsShortWithoutDots[m.month()];
16437        } else {
16438            return monthsShortWithDots[m.month()];
16439        }
16440    },
16441
16442    monthsRegex: monthsRegex,
16443    monthsShortRegex: monthsRegex,
16444    monthsStrictRegex: /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i,
16445    monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,
16446
16447    monthsParse: monthsParse,
16448    longMonthsParse: monthsParse,
16449    shortMonthsParse: monthsParse,
16450
16451    weekdays: 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split(
16452        '_'
16453    ),
16454    weekdaysShort: 'zo._ma._di._wo._do._vr._za.'.split('_'),
16455    weekdaysMin: 'zo_ma_di_wo_do_vr_za'.split('_'),
16456    weekdaysParseExact: true,
16457    longDateFormat: {
16458        LT: 'HH:mm',
16459        LTS: 'HH:mm:ss',
16460        L: 'DD-MM-YYYY',
16461        LL: 'D MMMM YYYY',
16462        LLL: 'D MMMM YYYY HH:mm',
16463        LLLL: 'dddd D MMMM YYYY HH:mm',
16464    },
16465    calendar: {
16466        sameDay: '[vandaag om] LT',
16467        nextDay: '[morgen om] LT',
16468        nextWeek: 'dddd [om] LT',
16469        lastDay: '[gisteren om] LT',
16470        lastWeek: '[afgelopen] dddd [om] LT',
16471        sameElse: 'L',
16472    },
16473    relativeTime: {
16474        future: 'over %s',
16475        past: '%s geleden',
16476        s: 'een paar seconden',
16477        ss: '%d seconden',
16478        m: 'één minuut',
16479        mm: '%d minuten',
16480        h: 'één uur',
16481        hh: '%d uur',
16482        d: 'één dag',
16483        dd: '%d dagen',
16484        w: 'één week',
16485        ww: '%d weken',
16486        M: 'één maand',
16487        MM: '%d maanden',
vendor: 4,844 bytes, lines 16488-16638
16488        y: 'één jaar',
16489        yy: '%d jaar',
16490    },
16491    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
16492    ordinal: function (number) {
16493        return (
16494            number +
16495            (number === 1 || number === 8 || number >= 20 ? 'ste' : 'de')
16496        );
16497    },
16498    week: {
16499        dow: 1, // Monday is the first day of the week.
16500        doy: 4, // The week that contains Jan 4th is the first week of the year.
16501    },
16502}));
16503
16504
16505/***/ }),
16506/* 101 */
16507/***/ (function(module, __webpack_exports__, __webpack_require__) {
16508
16509"use strict";
16510Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
16511/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
16512//! moment.js locale configuration
16513//! locale : Dutch (Belgium) [nl-be]
16514//! author : Joris Röling : https://github.com/jorisroling
16515//! author : Jacob Middag : https://github.com/middagj
16516
16517
16518
16519var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split(
16520        '_'
16521    ),
16522    monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split(
16523        '_'
16524    ),
16525    monthsParse = [
16526        /^jan/i,
16527        /^feb/i,
16528        /^maart|mrt.?$/i,
16529        /^apr/i,
16530        /^mei$/i,
16531        /^jun[i.]?$/i,
16532        /^jul[i.]?$/i,
16533        /^aug/i,
16534        /^sep/i,
16535        /^okt/i,
16536        /^nov/i,
16537        /^dec/i,
16538    ],
16539    monthsRegex = /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;
16540
16541/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('nl-be', {
16542    months: 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split(
16543        '_'
16544    ),
16545    monthsShort: function (m, format) {
16546        if (!m) {
16547            return monthsShortWithDots;
16548        } else if (/-MMM-/.test(format)) {
16549            return monthsShortWithoutDots[m.month()];
16550        } else {
16551            return monthsShortWithDots[m.month()];
16552        }
16553    },
16554
16555    monthsRegex: monthsRegex,
16556    monthsShortRegex: monthsRegex,
16557    monthsStrictRegex: /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i,
16558    monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,
16559
16560    monthsParse: monthsParse,
16561    longMonthsParse: monthsParse,
16562    shortMonthsParse: monthsParse,
16563
16564    weekdays: 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split(
16565        '_'
16566    ),
16567    weekdaysShort: 'zo._ma._di._wo._do._vr._za.'.split('_'),
16568    weekdaysMin: 'zo_ma_di_wo_do_vr_za'.split('_'),
16569    weekdaysParseExact: true,
16570    longDateFormat: {
16571        LT: 'HH:mm',
16572        LTS: 'HH:mm:ss',
16573        L: 'DD/MM/YYYY',
16574        LL: 'D MMMM YYYY',
16575        LLL: 'D MMMM YYYY HH:mm',
16576        LLLL: 'dddd D MMMM YYYY HH:mm',
16577    },
16578    calendar: {
16579        sameDay: '[vandaag om] LT',
16580        nextDay: '[morgen om] LT',
16581        nextWeek: 'dddd [om] LT',
16582        lastDay: '[gisteren om] LT',
16583        lastWeek: '[afgelopen] dddd [om] LT',
16584        sameElse: 'L',
16585    },
16586    relativeTime: {
16587        future: 'over %s',
16588        past: '%s geleden',
16589        s: 'een paar seconden',
16590        ss: '%d seconden',
16591        m: 'één minuut',
16592        mm: '%d minuten',
16593        h: 'één uur',
16594        hh: '%d uur',
16595        d: 'één dag',
16596        dd: '%d dagen',
16597        M: 'één maand',
16598        MM: '%d maanden',
16599        y: 'één jaar',
16600        yy: '%d jaar',
16601    },
16602    dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
16603    ordinal: function (number) {
16604        return (
16605            number +
16606            (number === 1 || number === 8 || number >= 20 ? 'ste' : 'de')
16607        );
16608    },
16609    week: {
16610        dow: 1, // Monday is the first day of the week.
16611        doy: 4, // The week that contains Jan 4th is the first week of the year.
16612    },
16613}));
16614
16615
16616/***/ }),
16617/* 102 */
16618/***/ (function(module, __webpack_exports__, __webpack_require__) {
16619
16620"use strict";
16621Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
16622/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
16623//! moment.js locale configuration
16624//! locale : Nynorsk [nn]
16625//! authors : https://github.com/mechuwind
16626//!           Stephen Ramthun : https://github.com/stephenramthun
16627
16628
16629
16630/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('nn', {
16631    months: 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split(
16632        '_'
16633    ),
16634    monthsShort: 'jan._feb._mars_apr._mai_juni_juli_aug._sep._okt._nov._des.'.split(
16635        '_'
16636    ),
16637    monthsParseExact: true,
16638    weekdays: 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),
16639    weekdaysShort: 'su._må._ty._on._to._fr._lau.'.split('_'),
16640    weekdaysMin: 'su_må_ty_on_to_fr_la'.split('_'),
16641    weekdaysParseExact: true,
16642    longDateFormat: {
16643        LT: 'HH:mm',
16644        LTS: 'HH:mm:ss',
16645        L: 'DD.MM.YYYY',
16646        LL: 'D. MMMM YYYY',
16647        LLL: 'D. MMMM YYYY [kl.] H:mm',
16648        LLLL: 'dddd D. MMMM YYYY [kl.] HH:mm',
16649    },
16650    calendar: {
16651        sameDay: '[I dag klokka] LT',
16652        nextDay: '[I morgon klokka] LT',
16653        nextWeek: 'dddd [klokka] LT',
16654        lastDay: '[I går klokka] LT',
16655        lastWeek: '[Føregåande] dddd [klokka] LT',
16656        sameElse: 'L',
16657    },
16658    relativeTime: {
16659        future: 'om %s',
16660        past: '%s sidan',
16661        s: 'nokre sekund',
16662        ss: '%d sekund',
16663        m: 'eit minutt',
16664        mm: '%d minutt',
16665        h: 'ein time',
16666        hh: '%d timar',
16667        d: 'ein dag',
16668        dd: '%d dagar',
16669        w: 'ei veke',
16670        ww: '%d veker',
16671        M: 'ein månad',
16672        MM: '%d månader',
16673        y: 'eit år',
16674        yy: '%d år',
16675    },
16676    dayOfMonthOrdinalParse: /\d{1,2}\./,
16677    ordinal: '%d.',
16678    week: {
16679        dow: 1, // Monday is the first day of the week.
16680        doy: 4, // The week that contains Jan 4th is the first week of the year.
16681    },
16682}));
16683
16684
16685/***/ }),
16686/* 103 */
16687/***/ (function(module, __webpack_exports__, __webpack_require__) {
16688
16689"use strict";
16690Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
16691/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
16692//! moment.js locale configuration
16693//! locale : Occitan, lengadocian dialecte [oc-lnc]
16694//! author : Quentin PAGÈS : https://github.com/Quenty31
16695
16696
16697
16698/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('oc-lnc', {
16699    months: {
16700        standalone: 'genièr_febrièr_març_abril_mai_junh_julhet_agost_setembre_octòbre_novembre_decembre'.split(
16701            '_'
16702        ),
16703        format: "de genièr_de febrièr_de març_d'abril_de mai_de junh_de julhet_d'agost_de setembre_d'octòbre_de novembre_de decembre".split(
16704            '_'
16705        ),
16706        isFormat: /D[oD]?(\s)+MMMM/,
16707    },
16708    monthsShort: 'gen._febr._març_abr._mai_junh_julh._ago._set._oct._nov._dec.'.split(
16709        '_'
16710    ),
16711    monthsParseExact: true,
16712    weekdays: 'dimenge_diluns_dimars_dimècres_dijòus_divendres_dissabte'.split(
16713        '_'
16714    ),
16715    weekdaysShort: 'dg._dl._dm._dc._dj._dv._ds.'.split('_'),
16716    weekdaysMin: 'dg_dl_dm_dc_dj_dv_ds'.split('_'),
16717    weekdaysParseExact: true,
16718    longDateFormat: {
16719        LT: 'H:mm',
16720        LTS: 'H:mm:ss',
16721        L: 'DD/MM/YYYY',
16722        LL: 'D MMMM [de] YYYY',
16723        ll: 'D MMM YYYY',
16724        LLL: 'D MMMM [de] YYYY [a] H:mm',
16725        lll: 'D MMM YYYY, H:mm',
16726        LLLL: 'dddd D MMMM [de] YYYY [a] H:mm',
16727        llll: 'ddd D MMM YYYY, H:mm',
16728    },
16729    calendar: {
16730        sameDay: '[uèi a] LT',
16731        nextDay: '[deman a] LT',
16732        nextWeek: 'dddd [a] LT',
16733        lastDay: '[ièr a] LT',
16734        lastWeek: 'dddd [passat a] LT',
16735        sameElse: 'L',
16736    },
16737    relativeTime: {
16738        future: "d'aquí %s",
16739        past: 'fa %s',
16740        s: 'unas segondas',
16741        ss: '%d segondas',
16742        m: 'una minuta',
16743        mm: '%d minutas',
16744        h: 'una ora',
16745        hh: '%d oras',
16746        d: 'un jorn',
16747        dd: '%d jorns',
16748        M: 'un mes',
16749        MM: '%d meses',
16750        y: 'un an',
16751        yy: '%d ans',
16752    },
16753    dayOfMonthOrdinalParse: /\d{1,2}(r|n|t|è|a)/,
16754    ordinal: function (number, period) {
16755        var output =
16756            number === 1
16757                ? 'r'
16758                : number === 2
16759                ? 'n'
16760                : number === 3
16761                ? 'r'
16762                : number === 4
16763                ? 't'
16764                : 'è';
16765        if (period === 'w' || period === 'W') {
16766            output = 'a';
16767        }
16768        return number + output;
16769    },
16770    week: {
16771        dow: 1, // Monday is the first day of the week.
16772        doy: 4,
16773    },
16774}));
16775
16776
16777/***/ }),
16778/* 104 */
16779/***/ (function(module, __webpack_exports__, __webpack_require__) {
16780
16781"use strict";
16782Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
16783/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
16784//! moment.js locale configuration
16785//! locale : Punjabi (India) [pa-in]
16786//! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit
16787
16788
16789
16790var symbolMap = {
16791        1: 'à©§',
16792        2: '੨',
16793        3: 'à©©',
16794        4: '੪',
16795        5: 'à©«',
16796        6: '੬',
16797        7: 'à©­',
16798        8: 'à©®',
16799        9: '੯',
16800        0: '੦',
16801    },
16802    numberMap = {
16803        'à©§': '1',
16804        '੨': '2',
16805        'à©©': '3',
16806        '੪': '4',
16807        'à©«': '5',
16808        '੬': '6',
16809        'à©­': '7',
16810        'à©®': '8',
16811        '੯': '9',
16812        '੦': '0',
16813    };
16814
16815/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('pa-in', {
16816    // There are months name as per Nanakshahi Calendar but they are not used as rigidly in modern Punjabi.
16817    months: 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split(
16818        '_'
16819    ),
16820    monthsShort: 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split(
16821        '_'
16822    ),
16823    weekdays: 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split(
16824        '_'
16825    ),
16826    weekdaysShort: 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),
16827    weekdaysMin: 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'),
16828    longDateFormat: {
16829        LT: 'A h:mm ਵਜੇ',
16830        LTS: 'A h:mm:ss ਵਜੇ',
16831        L: 'DD/MM/YYYY',
16832        LL: 'D MMMM YYYY',
16833        LLL: 'D MMMM YYYY, A h:mm ਵਜੇ',
16834        LLLL: 'dddd, D MMMM YYYY, A h:mm ਵਜੇ',
16835    },
16836    calendar: {
16837        sameDay: '[ਅਜ] LT',
16838        nextDay: '[ਕਲ] LT',
16839        nextWeek: '[ਅਗਲਾ] dddd, LT',
16840        lastDay: '[ਕਲ] LT',
16841        lastWeek: '[ਪਿਛਲੇ] dddd, LT',
16842        sameElse: 'L',
16843    },
16844    relativeTime: {
16845        future: '%s ਵਿੱਚ',
16846        past: '%s ਪਿਛਲੇ',
16847        s: 'ਕੁਝ ਸਕਿੰਟ',
16848        ss: '%d ਸਕਿੰਟ',
16849        m: 'ਇਕ ਮਿੰਟ',
16850        mm: '%d ਮਿੰਟ',
16851        h: 'ਇੱਕ ਘੰਟਾ',
16852        hh: '%d ਘੰਟੇ',
16853        d: 'ਇੱਕ ਦਿਨ',
16854        dd: '%d ਦਿਨ',
16855        M: 'ਇੱਕ ਮਹੀਨਾ',
16856        MM: '%d ਮਹੀਨੇ',
16857        y: 'ਇੱਕ ਸਾਲ',
16858        yy: '%d ਸਾਲ',
16859    },
16860    preparse: function (string) {
16861        return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) {
16862            return numberMap[match];
16863        });
16864    },
16865    postformat: function (string) {
16866        return string.replace(/\d/g, function (match) {
16867            return symbolMap[match];
16868        });
16869    },
16870    // Punjabi notation for meridiems are quite fuzzy in practice. While there exists
16871    // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi.
16872    meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,
16873    meridiemHour: function (hour, meridiem) {
16874        if (hour === 12) {
16875            hour = 0;
16876        }
16877        if (meridiem === 'ਰਾਤ') {
16878            return hour < 4 ? hour : hour + 12;
16879        } else if (meridiem === 'ਸਵੇਰ') {
16880            return hour;
16881        } else if (meridiem === 'ਦੁਪਹਿਰ') {
16882            return hour >= 10 ? hour : hour + 12;
16883        } else if (meridiem === 'ਸ਼ਾਮ') {
16884            return hour + 12;
16885        }
16886    },
16887    meridiem: function (hour, minute, isLower) {
16888        if (hour < 4) {
16889            return 'ਰਾਤ';
16890        } else if (hour < 10) {
16891            return 'ਸਵੇਰ';
16892        } else if (hour < 17) {
16893            return 'ਦੁਪਹਿਰ';
16894        } else if (hour < 20) {
16895            return 'ਸ਼ਾਮ';
16896        } else {
16897            return 'ਰਾਤ';
16898        }
16899    },
16900    week: {
16901        dow: 0, // Sunday is the first day of the week.
16902        doy: 6, // The week that contains Jan 6th is the first week of the year.
16903    },
16904}));
16905
16906
16907/***/ }),
16908/* 105 */
16909/***/ (function(module, __webpack_exports__, __webpack_require__) {
16910
16911"use strict";
16912Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
16913/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
16914//! moment.js locale configuration
16915//! locale : Polish [pl]
16916//! author : Rafal Hirsz : https://github.com/evoL
16917
16918
16919
vendor: 24,929 bytes, lines 16920-17659
16920var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split(
16921        '_'
16922    ),
16923    monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split(
16924        '_'
16925    ),
16926    monthsParse = [
16927        /^sty/i,
16928        /^lut/i,
16929        /^mar/i,
16930        /^kwi/i,
16931        /^maj/i,
16932        /^cze/i,
16933        /^lip/i,
16934        /^sie/i,
16935        /^wrz/i,
16936        /^paź/i,
16937        /^lis/i,
16938        /^gru/i,
16939    ];
16940function plural(n) {
16941    return n % 10 < 5 && n % 10 > 1 && ~~(n / 10) % 10 !== 1;
16942}
16943function translate(number, withoutSuffix, key) {
16944    var result = number + ' ';
16945    switch (key) {
16946        case 'ss':
16947            return result + (plural(number) ? 'sekundy' : 'sekund');
16948        case 'm':
16949            return withoutSuffix ? 'minuta' : 'minutę';
16950        case 'mm':
16951            return result + (plural(number) ? 'minuty' : 'minut');
16952        case 'h':
16953            return withoutSuffix ? 'godzina' : 'godzinę';
16954        case 'hh':
16955            return result + (plural(number) ? 'godziny' : 'godzin');
16956        case 'ww':
16957            return result + (plural(number) ? 'tygodnie' : 'tygodni');
16958        case 'MM':
16959            return result + (plural(number) ? 'miesiące' : 'miesięcy');
16960        case 'yy':
16961            return result + (plural(number) ? 'lata' : 'lat');
16962    }
16963}
16964
16965/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('pl', {
16966    months: function (momentToFormat, format) {
16967        if (!momentToFormat) {
16968            return monthsNominative;
16969        } else if (/D MMMM/.test(format)) {
16970            return monthsSubjective[momentToFormat.month()];
16971        } else {
16972            return monthsNominative[momentToFormat.month()];
16973        }
16974    },
16975    monthsShort: 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),
16976    monthsParse: monthsParse,
16977    longMonthsParse: monthsParse,
16978    shortMonthsParse: monthsParse,
16979    weekdays: 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split(
16980        '_'
16981    ),
16982    weekdaysShort: 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),
16983    weekdaysMin: 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),
16984    longDateFormat: {
16985        LT: 'HH:mm',
16986        LTS: 'HH:mm:ss',
16987        L: 'DD.MM.YYYY',
16988        LL: 'D MMMM YYYY',
16989        LLL: 'D MMMM YYYY HH:mm',
16990        LLLL: 'dddd, D MMMM YYYY HH:mm',
16991    },
16992    calendar: {
16993        sameDay: '[Dziś o] LT',
16994        nextDay: '[Jutro o] LT',
16995        nextWeek: function () {
16996            switch (this.day()) {
16997                case 0:
16998                    return '[W niedzielę o] LT';
16999
17000                case 2:
17001                    return '[We wtorek o] LT';
17002
17003                case 3:
17004                    return '[W środę o] LT';
17005
17006                case 6:
17007                    return '[W sobotę o] LT';
17008
17009                default:
17010                    return '[W] dddd [o] LT';
17011            }
17012        },
17013        lastDay: '[Wczoraj o] LT',
17014        lastWeek: function () {
17015            switch (this.day()) {
17016                case 0:
17017                    return '[W zeszłą niedzielę o] LT';
17018                case 3:
17019                    return '[W zeszłą środę o] LT';
17020                case 6:
17021                    return '[W zeszłą sobotę o] LT';
17022                default:
17023                    return '[W zeszły] dddd [o] LT';
17024            }
17025        },
17026        sameElse: 'L',
17027    },
17028    relativeTime: {
17029        future: 'za %s',
17030        past: '%s temu',
17031        s: 'kilka sekund',
17032        ss: translate,
17033        m: translate,
17034        mm: translate,
17035        h: translate,
17036        hh: translate,
17037        d: '1 dzień',
17038        dd: '%d dni',
17039        w: 'tydzień',
17040        ww: translate,
17041        M: 'miesiąc',
17042        MM: translate,
17043        y: 'rok',
17044        yy: translate,
17045    },
17046    dayOfMonthOrdinalParse: /\d{1,2}\./,
17047    ordinal: '%d.',
17048    week: {
17049        dow: 1, // Monday is the first day of the week.
17050        doy: 4, // The week that contains Jan 4th is the first week of the year.
17051    },
17052}));
17053
17054
17055/***/ }),
17056/* 106 */
17057/***/ (function(module, __webpack_exports__, __webpack_require__) {
17058
17059"use strict";
17060Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
17061/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
17062//! moment.js locale configuration
17063//! locale : Portuguese [pt]
17064//! author : Jefferson : https://github.com/jalex79
17065
17066
17067
17068/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('pt', {
17069    months: 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split(
17070        '_'
17071    ),
17072    monthsShort: 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'),
17073    weekdays: 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split(
17074        '_'
17075    ),
17076    weekdaysShort: 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),
17077    weekdaysMin: 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'),
17078    weekdaysParseExact: true,
17079    longDateFormat: {
17080        LT: 'HH:mm',
17081        LTS: 'HH:mm:ss',
17082        L: 'DD/MM/YYYY',
17083        LL: 'D [de] MMMM [de] YYYY',
17084        LLL: 'D [de] MMMM [de] YYYY HH:mm',
17085        LLLL: 'dddd, D [de] MMMM [de] YYYY HH:mm',
17086    },
17087    calendar: {
17088        sameDay: '[Hoje às] LT',
17089        nextDay: '[Amanhã às] LT',
17090        nextWeek: 'dddd [às] LT',
17091        lastDay: '[Ontem às] LT',
17092        lastWeek: function () {
17093            return this.day() === 0 || this.day() === 6
17094                ? '[Último] dddd [às] LT' // Saturday + Sunday
17095                : '[Última] dddd [às] LT'; // Monday - Friday
17096        },
17097        sameElse: 'L',
17098    },
17099    relativeTime: {
17100        future: 'em %s',
17101        past: 'há %s',
17102        s: 'segundos',
17103        ss: '%d segundos',
17104        m: 'um minuto',
17105        mm: '%d minutos',
17106        h: 'uma hora',
17107        hh: '%d horas',
17108        d: 'um dia',
17109        dd: '%d dias',
17110        w: 'uma semana',
17111        ww: '%d semanas',
17112        M: 'um mês',
17113        MM: '%d meses',
17114        y: 'um ano',
17115        yy: '%d anos',
17116    },
17117    dayOfMonthOrdinalParse: /\d{1,2}º/,
17118    ordinal: '%dº',
17119    week: {
17120        dow: 1, // Monday is the first day of the week.
17121        doy: 4, // The week that contains Jan 4th is the first week of the year.
17122    },
17123}));
17124
17125
17126/***/ }),
17127/* 107 */
17128/***/ (function(module, __webpack_exports__, __webpack_require__) {
17129
17130"use strict";
17131Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
17132/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
17133//! moment.js locale configuration
17134//! locale : Portuguese (Brazil) [pt-br]
17135//! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira
17136
17137
17138
17139/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('pt-br', {
17140    months: 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split(
17141        '_'
17142    ),
17143    monthsShort: 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'),
17144    weekdays: 'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split(
17145        '_'
17146    ),
17147    weekdaysShort: 'dom_seg_ter_qua_qui_sex_sáb'.split('_'),
17148    weekdaysMin: 'do_2ª_3ª_4ª_5ª_6ª_sá'.split('_'),
17149    weekdaysParseExact: true,
17150    longDateFormat: {
17151        LT: 'HH:mm',
17152        LTS: 'HH:mm:ss',
17153        L: 'DD/MM/YYYY',
17154        LL: 'D [de] MMMM [de] YYYY',
17155        LLL: 'D [de] MMMM [de] YYYY [às] HH:mm',
17156        LLLL: 'dddd, D [de] MMMM [de] YYYY [às] HH:mm',
17157    },
17158    calendar: {
17159        sameDay: '[Hoje às] LT',
17160        nextDay: '[Amanhã às] LT',
17161        nextWeek: 'dddd [às] LT',
17162        lastDay: '[Ontem às] LT',
17163        lastWeek: function () {
17164            return this.day() === 0 || this.day() === 6
17165                ? '[Último] dddd [às] LT' // Saturday + Sunday
17166                : '[Última] dddd [às] LT'; // Monday - Friday
17167        },
17168        sameElse: 'L',
17169    },
17170    relativeTime: {
17171        future: 'em %s',
17172        past: 'há %s',
17173        s: 'poucos segundos',
17174        ss: '%d segundos',
17175        m: 'um minuto',
17176        mm: '%d minutos',
17177        h: 'uma hora',
17178        hh: '%d horas',
17179        d: 'um dia',
17180        dd: '%d dias',
17181        M: 'um mês',
17182        MM: '%d meses',
17183        y: 'um ano',
17184        yy: '%d anos',
17185    },
17186    dayOfMonthOrdinalParse: /\d{1,2}º/,
17187    ordinal: '%dº',
17188    invalidDate: 'Data inválida',
17189}));
17190
17191
17192/***/ }),
17193/* 108 */
17194/***/ (function(module, __webpack_exports__, __webpack_require__) {
17195
17196"use strict";
17197Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
17198/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
17199//! moment.js locale configuration
17200//! locale : Romanian [ro]
17201//! author : Vlad Gurdiga : https://github.com/gurdiga
17202//! author : Valentin Agachi : https://github.com/avaly
17203//! author : Emanuel Cepoi : https://github.com/cepem
17204
17205
17206
17207function relativeTimeWithPlural(number, withoutSuffix, key) {
17208    var format = {
17209            ss: 'secunde',
17210            mm: 'minute',
17211            hh: 'ore',
17212            dd: 'zile',
17213            ww: 'săptămâni',
17214            MM: 'luni',
17215            yy: 'ani',
17216        },
17217        separator = ' ';
17218    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {
17219        separator = ' de ';
17220    }
17221    return number + separator + format[key];
17222}
17223
17224/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ro', {
17225    months: 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split(
17226        '_'
17227    ),
17228    monthsShort: 'ian._feb._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split(
17229        '_'
17230    ),
17231    monthsParseExact: true,
17232    weekdays: 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),
17233    weekdaysShort: 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),
17234    weekdaysMin: 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),
17235    longDateFormat: {
17236        LT: 'H:mm',
17237        LTS: 'H:mm:ss',
17238        L: 'DD.MM.YYYY',
17239        LL: 'D MMMM YYYY',
17240        LLL: 'D MMMM YYYY H:mm',
17241        LLLL: 'dddd, D MMMM YYYY H:mm',
17242    },
17243    calendar: {
17244        sameDay: '[azi la] LT',
17245        nextDay: '[mâine la] LT',
17246        nextWeek: 'dddd [la] LT',
17247        lastDay: '[ieri la] LT',
17248        lastWeek: '[fosta] dddd [la] LT',
17249        sameElse: 'L',
17250    },
17251    relativeTime: {
17252        future: 'peste %s',
17253        past: '%s în urmă',
17254        s: 'câteva secunde',
17255        ss: relativeTimeWithPlural,
17256        m: 'un minut',
17257        mm: relativeTimeWithPlural,
17258        h: 'o oră',
17259        hh: relativeTimeWithPlural,
17260        d: 'o zi',
17261        dd: relativeTimeWithPlural,
17262        w: 'o săptămână',
17263        ww: relativeTimeWithPlural,
17264        M: 'o lună',
17265        MM: relativeTimeWithPlural,
17266        y: 'un an',
17267        yy: relativeTimeWithPlural,
17268    },
17269    week: {
17270        dow: 1, // Monday is the first day of the week.
17271        doy: 7, // The week that contains Jan 7th is the first week of the year.
17272    },
17273}));
17274
17275
17276/***/ }),
17277/* 109 */
17278/***/ (function(module, __webpack_exports__, __webpack_require__) {
17279
17280"use strict";
17281Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
17282/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
17283//! moment.js locale configuration
17284//! locale : Russian [ru]
17285//! author : Viktorminator : https://github.com/Viktorminator
17286//! author : Menelion Elensúle : https://github.com/Oire
17287//! author : Коренберг Марк : https://github.com/socketpair
17288
17289
17290
17291function plural(word, num) {
17292    var forms = word.split('_');
17293    return num % 10 === 1 && num % 100 !== 11
17294        ? forms[0]
17295        : num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20)
17296        ? forms[1]
17297        : forms[2];
17298}
17299function relativeTimeWithPlural(number, withoutSuffix, key) {
17300    var format = {
17301        ss: withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд',
17302        mm: withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',
17303        hh: 'час_часа_часов',
17304        dd: 'день_дня_дней',
17305        ww: 'неделя_недели_недель',
17306        MM: 'месяц_месяца_месяцев',
17307        yy: 'год_года_лет',
17308    };
17309    if (key === 'm') {
17310        return withoutSuffix ? 'минута' : 'минуту';
17311    } else {
17312        return number + ' ' + plural(format[key], +number);
17313    }
17314}
17315var monthsParse = [
17316    /^янв/i,
17317    /^фев/i,
17318    /^мар/i,
17319    /^апр/i,
17320    /^ма[йя]/i,
17321    /^июн/i,
17322    /^июл/i,
17323    /^авг/i,
17324    /^сен/i,
17325    /^окт/i,
17326    /^ноя/i,
17327    /^дек/i,
17328];
17329
17330// http://new.gramota.ru/spravka/rules/139-prop : § 103
17331// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637
17332// CLDR data:          http://www.unicode.org/cldr/charts/28/summary/ru.html#1753
17333/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ru', {
17334    months: {
17335        format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split(
17336            '_'
17337        ),
17338        standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split(
17339            '_'
17340        ),
17341    },
17342    monthsShort: {
17343        // по CLDR именно "июл." и "июн.", но какой смысл менять букву на точку?
17344        format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split(
17345            '_'
17346        ),
17347        standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split(
17348            '_'
17349        ),
17350    },
17351    weekdays: {
17352        standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split(
17353            '_'
17354        ),
17355        format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split(
17356            '_'
17357        ),
17358        isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?] ?dddd/,
17359    },
17360    weekdaysShort: 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
17361    weekdaysMin: 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
17362    monthsParse: monthsParse,
17363    longMonthsParse: monthsParse,
17364    shortMonthsParse: monthsParse,
17365
17366    // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки
17367    monthsRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,
17368
17369    // копия предыдущего
17370    monthsShortRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,
17371
17372    // полные названия с падежами
17373    monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,
17374
17375    // Выражение, которое соответствует только сокращённым формам
17376    monthsShortStrictRegex: /^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i,
17377    longDateFormat: {
17378        LT: 'H:mm',
17379        LTS: 'H:mm:ss',
17380        L: 'DD.MM.YYYY',
17381        LL: 'D MMMM YYYY г.',
17382        LLL: 'D MMMM YYYY г., H:mm',
17383        LLLL: 'dddd, D MMMM YYYY г., H:mm',
17384    },
17385    calendar: {
17386        sameDay: '[Сегодня, в] LT',
17387        nextDay: '[Завтра, в] LT',
17388        lastDay: '[Вчера, в] LT',
17389        nextWeek: function (now) {
17390            if (now.week() !== this.week()) {
17391                switch (this.day()) {
17392                    case 0:
17393                        return '[В следующее] dddd, [в] LT';
17394                    case 1:
17395                    case 2:
17396                    case 4:
17397                        return '[В следующий] dddd, [в] LT';
17398                    case 3:
17399                    case 5:
17400                    case 6:
17401                        return '[В следующую] dddd, [в] LT';
17402                }
17403            } else {
17404                if (this.day() === 2) {
17405                    return '[Во] dddd, [в] LT';
17406                } else {
17407                    return '[В] dddd, [в] LT';
17408                }
17409            }
17410        },
17411        lastWeek: function (now) {
17412            if (now.week() !== this.week()) {
17413                switch (this.day()) {
17414                    case 0:
17415                        return '[В прошлое] dddd, [в] LT';
17416                    case 1:
17417                    case 2:
17418                    case 4:
17419                        return '[В прошлый] dddd, [в] LT';
17420                    case 3:
17421                    case 5:
17422                    case 6:
17423                        return '[В прошлую] dddd, [в] LT';
17424                }
17425            } else {
17426                if (this.day() === 2) {
17427                    return '[Во] dddd, [в] LT';
17428                } else {
17429                    return '[В] dddd, [в] LT';
17430                }
17431            }
17432        },
17433        sameElse: 'L',
17434    },
17435    relativeTime: {
17436        future: 'через %s',
17437        past: '%s назад',
17438        s: 'несколько секунд',
17439        ss: relativeTimeWithPlural,
17440        m: relativeTimeWithPlural,
17441        mm: relativeTimeWithPlural,
17442        h: 'час',
17443        hh: relativeTimeWithPlural,
17444        d: 'день',
17445        dd: relativeTimeWithPlural,
17446        w: 'неделя',
17447        ww: relativeTimeWithPlural,
17448        M: 'месяц',
17449        MM: relativeTimeWithPlural,
17450        y: 'год',
17451        yy: relativeTimeWithPlural,
17452    },
17453    meridiemParse: /ночи|утра|дня|вечера/i,
17454    isPM: function (input) {
17455        return /^(дня|вечера)$/.test(input);
17456    },
17457    meridiem: function (hour, minute, isLower) {
17458        if (hour < 4) {
17459            return 'ночи';
17460        } else if (hour < 12) {
17461            return 'утра';
17462        } else if (hour < 17) {
17463            return 'дня';
17464        } else {
17465            return 'вечера';
17466        }
17467    },
17468    dayOfMonthOrdinalParse: /\d{1,2}-(й|го|я)/,
17469    ordinal: function (number, period) {
17470        switch (period) {
17471            case 'M':
17472            case 'd':
17473            case 'DDD':
17474                return number + '-й';
17475            case 'D':
17476                return number + '-го';
17477            case 'w':
17478            case 'W':
17479                return number + '-я';
17480            default:
17481                return number;
17482        }
17483    },
17484    week: {
17485        dow: 1, // Monday is the first day of the week.
17486        doy: 4, // The week that contains Jan 4th is the first week of the year.
17487    },
17488}));
17489
17490
17491/***/ }),
17492/* 110 */
17493/***/ (function(module, __webpack_exports__, __webpack_require__) {
17494
17495"use strict";
17496Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
17497/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
17498//! moment.js locale configuration
17499//! locale : Sindhi [sd]
17500//! author : Narain Sagar : https://github.com/narainsagar
17501
17502
17503
17504var months = [
17505        'جنوري',
17506        'فيبروري',
17507        'مارچ',
17508        'اپريل',
17509        'مئي',
17510        'جون',
17511        'جولاءِ',
17512        'آگسٽ',
17513        'سيپٽمبر',
17514        'آڪٽوبر',
17515        'نومبر',
17516        'ڊسمبر',
17517    ],
17518    days = ['آچر', 'سومر', 'اڱارو', 'اربع', 'خميس', 'جمع', 'ڇنڇر'];
17519
17520/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('sd', {
17521    months: months,
17522    monthsShort: months,
17523    weekdays: days,
17524    weekdaysShort: days,
17525    weekdaysMin: days,
17526    longDateFormat: {
17527        LT: 'HH:mm',
17528        LTS: 'HH:mm:ss',
17529        L: 'DD/MM/YYYY',
17530        LL: 'D MMMM YYYY',
17531        LLL: 'D MMMM YYYY HH:mm',
17532        LLLL: 'dddd، D MMMM YYYY HH:mm',
17533    },
17534    meridiemParse: /صبح|شام/,
17535    isPM: function (input) {
17536        return 'شام' === input;
17537    },
17538    meridiem: function (hour, minute, isLower) {
17539        if (hour < 12) {
17540            return 'صبح';
17541        }
17542        return 'شام';
17543    },
17544    calendar: {
17545        sameDay: '[اڄ] LT',
17546        nextDay: '[سڀاڻي] LT',
17547        nextWeek: 'dddd [اڳين هفتي تي] LT',
17548        lastDay: '[ڪالهه] LT',
17549        lastWeek: '[گزريل هفتي] dddd [تي] LT',
17550        sameElse: 'L',
17551    },
17552    relativeTime: {
17553        future: '%s پوء',
17554        past: '%s اڳ',
17555        s: 'چند سيڪنڊ',
17556        ss: '%d سيڪنڊ',
17557        m: 'هڪ منٽ',
17558        mm: '%d منٽ',
17559        h: 'هڪ ڪلاڪ',
17560        hh: '%d ڪلاڪ',
17561        d: 'هڪ ڏينهن',
17562        dd: '%d ڏينهن',
17563        M: 'هڪ مهينو',
17564        MM: '%d مهينا',
17565        y: 'هڪ سال',
17566        yy: '%d سال',
17567    },
17568    preparse: function (string) {
17569        return string.replace(/،/g, ',');
17570    },
17571    postformat: function (string) {
17572        return string.replace(/,/g, '،');
17573    },
17574    week: {
17575        dow: 1, // Monday is the first day of the week.
17576        doy: 4, // The week that contains Jan 4th is the first week of the year.
17577    },
17578}));
17579
17580
17581/***/ }),
17582/* 111 */
17583/***/ (function(module, __webpack_exports__, __webpack_require__) {
17584
17585"use strict";
17586Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
17587/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
17588//! moment.js locale configuration
17589//! locale : Northern Sami [se]
17590//! authors : BÃ¥rd Rolstad Henriksen : https://github.com/karamell
17591
17592
17593
17594/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('se', {
17595    months: 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split(
17596        '_'
17597    ),
17598    monthsShort: 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split(
17599        '_'
17600    ),
17601    weekdays: 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split(
17602        '_'
17603    ),
17604    weekdaysShort: 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'),
17605    weekdaysMin: 's_v_m_g_d_b_L'.split('_'),
17606    longDateFormat: {
17607        LT: 'HH:mm',
17608        LTS: 'HH:mm:ss',
17609        L: 'DD.MM.YYYY',
17610        LL: 'MMMM D. [b.] YYYY',
17611        LLL: 'MMMM D. [b.] YYYY [ti.] HH:mm',
17612        LLLL: 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm',
17613    },
17614    calendar: {
17615        sameDay: '[otne ti] LT',
17616        nextDay: '[ihttin ti] LT',
17617        nextWeek: 'dddd [ti] LT',
17618        lastDay: '[ikte ti] LT',
17619        lastWeek: '[ovddit] dddd [ti] LT',
17620        sameElse: 'L',
17621    },
17622    relativeTime: {
17623        future: '%s geažes',
17624        past: 'maŋit %s',
17625        s: 'moadde sekunddat',
17626        ss: '%d sekunddat',
17627        m: 'okta minuhta',
17628        mm: '%d minuhtat',
17629        h: 'okta diimmu',
17630        hh: '%d diimmut',
17631        d: 'okta beaivi',
17632        dd: '%d beaivvit',
17633        M: 'okta mánnu',
17634        MM: '%d mánut',
17635        y: 'okta jahki',
17636        yy: '%d jagit',
17637    },
17638    dayOfMonthOrdinalParse: /\d{1,2}\./,
17639    ordinal: '%d.',
17640    week: {
17641        dow: 1, // Monday is the first day of the week.
17642        doy: 4, // The week that contains Jan 4th is the first week of the year.
17643    },
17644}));
17645
17646
17647/***/ }),
17648/* 112 */
17649/***/ (function(module, __webpack_exports__, __webpack_require__) {
17650
17651"use strict";
17652Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
17653/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
17654//! moment.js locale configuration
17655//! locale : Sinhalese [si]
17656//! author : Sampath Sitinamaluwa : https://github.com/sampathsris
17657
17658
17659
vendor: 16,384 bytes, lines 17660-18109
17660/*jshint -W100*/
17661/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('si', {
17662    months: 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split(
17663        '_'
17664    ),
17665    monthsShort: 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split(
17666        '_'
17667    ),
17668    weekdays: 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split(
17669        '_'
17670    ),
17671    weekdaysShort: 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'),
17672    weekdaysMin: 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'),
17673    weekdaysParseExact: true,
17674    longDateFormat: {
17675        LT: 'a h:mm',
17676        LTS: 'a h:mm:ss',
17677        L: 'YYYY/MM/DD',
17678        LL: 'YYYY MMMM D',
17679        LLL: 'YYYY MMMM D, a h:mm',
17680        LLLL: 'YYYY MMMM D [වැනි] dddd, a h:mm:ss',
17681    },
17682    calendar: {
17683        sameDay: '[අද] LT[ට]',
17684        nextDay: '[හෙට] LT[ට]',
17685        nextWeek: 'dddd LT[à¶§]',
17686        lastDay: '[ඊයේ] LT[ට]',
17687        lastWeek: '[පසුගිය] dddd LT[ට]',
17688        sameElse: 'L',
17689    },
17690    relativeTime: {
17691        future: '%sකින්',
17692        past: '%sකට පෙර',
17693        s: 'තත්පර කිහිපය',
17694        ss: 'තත්පර %d',
17695        m: 'මිනිත්තුව',
17696        mm: 'මිනිත්තු %d',
17697        h: 'පැය',
17698        hh: 'පැය %d',
17699        d: 'දිනය',
17700        dd: 'දින %d',
17701        M: 'මාසය',
17702        MM: 'මාස %d',
17703        y: 'වසර',
17704        yy: 'වසර %d',
17705    },
17706    dayOfMonthOrdinalParse: /\d{1,2} වැනි/,
17707    ordinal: function (number) {
17708        return number + ' වැනි';
17709    },
17710    meridiemParse: /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,
17711    isPM: function (input) {
17712        return input === 'ප.ව.' || input === 'පස් වරු';
17713    },
17714    meridiem: function (hours, minutes, isLower) {
17715        if (hours > 11) {
17716            return isLower ? 'ප.ව.' : 'පස් වරු';
17717        } else {
17718            return isLower ? 'පෙ.ව.' : 'පෙර වරු';
17719        }
17720    },
17721}));
17722
17723
17724/***/ }),
17725/* 113 */
17726/***/ (function(module, __webpack_exports__, __webpack_require__) {
17727
17728"use strict";
17729Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
17730/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
17731//! moment.js locale configuration
17732//! locale : Slovak [sk]
17733//! author : Martin Minka : https://github.com/k2s
17734//! based on work of petrbela : https://github.com/petrbela
17735
17736
17737
17738var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split(
17739        '_'
17740    ),
17741    monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');
17742function plural(n) {
17743    return n > 1 && n < 5;
17744}
17745function translate(number, withoutSuffix, key, isFuture) {
17746    var result = number + ' ';
17747    switch (key) {
17748        case 's': // a few seconds / in a few seconds / a few seconds ago
17749            return withoutSuffix || isFuture ? 'pár sekúnd' : 'pár sekundami';
17750        case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago
17751            if (withoutSuffix || isFuture) {
17752                return result + (plural(number) ? 'sekundy' : 'sekúnd');
17753            } else {
17754                return result + 'sekundami';
17755            }
17756        case 'm': // a minute / in a minute / a minute ago
17757            return withoutSuffix ? 'minúta' : isFuture ? 'minútu' : 'minútou';
17758        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
17759            if (withoutSuffix || isFuture) {
17760                return result + (plural(number) ? 'minúty' : 'minút');
17761            } else {
17762                return result + 'minútami';
17763            }
17764        case 'h': // an hour / in an hour / an hour ago
17765            return withoutSuffix ? 'hodina' : isFuture ? 'hodinu' : 'hodinou';
17766        case 'hh': // 9 hours / in 9 hours / 9 hours ago
17767            if (withoutSuffix || isFuture) {
17768                return result + (plural(number) ? 'hodiny' : 'hodín');
17769            } else {
17770                return result + 'hodinami';
17771            }
17772        case 'd': // a day / in a day / a day ago
17773            return withoutSuffix || isFuture ? 'deň' : 'dňom';
17774        case 'dd': // 9 days / in 9 days / 9 days ago
17775            if (withoutSuffix || isFuture) {
17776                return result + (plural(number) ? 'dni' : 'dní');
17777            } else {
17778                return result + 'dňami';
17779            }
17780        case 'M': // a month / in a month / a month ago
17781            return withoutSuffix || isFuture ? 'mesiac' : 'mesiacom';
17782        case 'MM': // 9 months / in 9 months / 9 months ago
17783            if (withoutSuffix || isFuture) {
17784                return result + (plural(number) ? 'mesiace' : 'mesiacov');
17785            } else {
17786                return result + 'mesiacmi';
17787            }
17788        case 'y': // a year / in a year / a year ago
17789            return withoutSuffix || isFuture ? 'rok' : 'rokom';
17790        case 'yy': // 9 years / in 9 years / 9 years ago
17791            if (withoutSuffix || isFuture) {
17792                return result + (plural(number) ? 'roky' : 'rokov');
17793            } else {
17794                return result + 'rokmi';
17795            }
17796    }
17797}
17798
17799/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('sk', {
17800    months: months,
17801    monthsShort: monthsShort,
17802    weekdays: 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),
17803    weekdaysShort: 'ne_po_ut_st_št_pi_so'.split('_'),
17804    weekdaysMin: 'ne_po_ut_st_št_pi_so'.split('_'),
17805    longDateFormat: {
17806        LT: 'H:mm',
17807        LTS: 'H:mm:ss',
17808        L: 'DD.MM.YYYY',
17809        LL: 'D. MMMM YYYY',
17810        LLL: 'D. MMMM YYYY H:mm',
17811        LLLL: 'dddd D. MMMM YYYY H:mm',
17812    },
17813    calendar: {
17814        sameDay: '[dnes o] LT',
17815        nextDay: '[zajtra o] LT',
17816        nextWeek: function () {
17817            switch (this.day()) {
17818                case 0:
17819                    return '[v nedeľu o] LT';
17820                case 1:
17821                case 2:
17822                    return '[v] dddd [o] LT';
17823                case 3:
17824                    return '[v stredu o] LT';
17825                case 4:
17826                    return '[vo štvrtok o] LT';
17827                case 5:
17828                    return '[v piatok o] LT';
17829                case 6:
17830                    return '[v sobotu o] LT';
17831            }
17832        },
17833        lastDay: '[včera o] LT',
17834        lastWeek: function () {
17835            switch (this.day()) {
17836                case 0:
17837                    return '[minulú nedeľu o] LT';
17838                case 1:
17839                case 2:
17840                    return '[minulý] dddd [o] LT';
17841                case 3:
17842                    return '[minulú stredu o] LT';
17843                case 4:
17844                case 5:
17845                    return '[minulý] dddd [o] LT';
17846                case 6:
17847                    return '[minulú sobotu o] LT';
17848            }
17849        },
17850        sameElse: 'L',
17851    },
17852    relativeTime: {
17853        future: 'za %s',
17854        past: 'pred %s',
17855        s: translate,
17856        ss: translate,
17857        m: translate,
17858        mm: translate,
17859        h: translate,
17860        hh: translate,
17861        d: translate,
17862        dd: translate,
17863        M: translate,
17864        MM: translate,
17865        y: translate,
17866        yy: translate,
17867    },
17868    dayOfMonthOrdinalParse: /\d{1,2}\./,
17869    ordinal: '%d.',
17870    week: {
17871        dow: 1, // Monday is the first day of the week.
17872        doy: 4, // The week that contains Jan 4th is the first week of the year.
17873    },
17874}));
17875
17876
17877/***/ }),
17878/* 114 */
17879/***/ (function(module, __webpack_exports__, __webpack_require__) {
17880
17881"use strict";
17882Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
17883/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
17884//! moment.js locale configuration
17885//! locale : Slovenian [sl]
17886//! author : Robert Sedovšek : https://github.com/sedovsek
17887
17888
17889
17890function processRelativeTime(number, withoutSuffix, key, isFuture) {
17891    var result = number + ' ';
17892    switch (key) {
17893        case 's':
17894            return withoutSuffix || isFuture
17895                ? 'nekaj sekund'
17896                : 'nekaj sekundami';
17897        case 'ss':
17898            if (number === 1) {
17899                result += withoutSuffix ? 'sekundo' : 'sekundi';
17900            } else if (number === 2) {
17901                result += withoutSuffix || isFuture ? 'sekundi' : 'sekundah';
17902            } else if (number < 5) {
17903                result += withoutSuffix || isFuture ? 'sekunde' : 'sekundah';
17904            } else {
17905                result += 'sekund';
17906            }
17907            return result;
17908        case 'm':
17909            return withoutSuffix ? 'ena minuta' : 'eno minuto';
17910        case 'mm':
17911            if (number === 1) {
17912                result += withoutSuffix ? 'minuta' : 'minuto';
17913            } else if (number === 2) {
17914                result += withoutSuffix || isFuture ? 'minuti' : 'minutama';
17915            } else if (number < 5) {
17916                result += withoutSuffix || isFuture ? 'minute' : 'minutami';
17917            } else {
17918                result += withoutSuffix || isFuture ? 'minut' : 'minutami';
17919            }
17920            return result;
17921        case 'h':
17922            return withoutSuffix ? 'ena ura' : 'eno uro';
17923        case 'hh':
17924            if (number === 1) {
17925                result += withoutSuffix ? 'ura' : 'uro';
17926            } else if (number === 2) {
17927                result += withoutSuffix || isFuture ? 'uri' : 'urama';
17928            } else if (number < 5) {
17929                result += withoutSuffix || isFuture ? 'ure' : 'urami';
17930            } else {
17931                result += withoutSuffix || isFuture ? 'ur' : 'urami';
17932            }
17933            return result;
17934        case 'd':
17935            return withoutSuffix || isFuture ? 'en dan' : 'enim dnem';
17936        case 'dd':
17937            if (number === 1) {
17938                result += withoutSuffix || isFuture ? 'dan' : 'dnem';
17939            } else if (number === 2) {
17940                result += withoutSuffix || isFuture ? 'dni' : 'dnevoma';
17941            } else {
17942                result += withoutSuffix || isFuture ? 'dni' : 'dnevi';
17943            }
17944            return result;
17945        case 'M':
17946            return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem';
17947        case 'MM':
17948            if (number === 1) {
17949                result += withoutSuffix || isFuture ? 'mesec' : 'mesecem';
17950            } else if (number === 2) {
17951                result += withoutSuffix || isFuture ? 'meseca' : 'mesecema';
17952            } else if (number < 5) {
17953                result += withoutSuffix || isFuture ? 'mesece' : 'meseci';
17954            } else {
17955                result += withoutSuffix || isFuture ? 'mesecev' : 'meseci';
17956            }
17957            return result;
17958        case 'y':
17959            return withoutSuffix || isFuture ? 'eno leto' : 'enim letom';
17960        case 'yy':
17961            if (number === 1) {
17962                result += withoutSuffix || isFuture ? 'leto' : 'letom';
17963            } else if (number === 2) {
17964                result += withoutSuffix || isFuture ? 'leti' : 'letoma';
17965            } else if (number < 5) {
17966                result += withoutSuffix || isFuture ? 'leta' : 'leti';
17967            } else {
17968                result += withoutSuffix || isFuture ? 'let' : 'leti';
17969            }
17970            return result;
17971    }
17972}
17973
17974/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('sl', {
17975    months: 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split(
17976        '_'
17977    ),
17978    monthsShort: 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split(
17979        '_'
17980    ),
17981    monthsParseExact: true,
17982    weekdays: 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),
17983    weekdaysShort: 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),
17984    weekdaysMin: 'ne_po_to_sr_če_pe_so'.split('_'),
17985    weekdaysParseExact: true,
17986    longDateFormat: {
17987        LT: 'H:mm',
17988        LTS: 'H:mm:ss',
17989        L: 'DD. MM. YYYY',
17990        LL: 'D. MMMM YYYY',
17991        LLL: 'D. MMMM YYYY H:mm',
17992        LLLL: 'dddd, D. MMMM YYYY H:mm',
17993    },
17994    calendar: {
17995        sameDay: '[danes ob] LT',
17996        nextDay: '[jutri ob] LT',
17997
17998        nextWeek: function () {
17999            switch (this.day()) {
18000                case 0:
18001                    return '[v] [nedeljo] [ob] LT';
18002                case 3:
18003                    return '[v] [sredo] [ob] LT';
18004                case 6:
18005                    return '[v] [soboto] [ob] LT';
18006                case 1:
18007                case 2:
18008                case 4:
18009                case 5:
18010                    return '[v] dddd [ob] LT';
18011            }
18012        },
18013        lastDay: '[včeraj ob] LT',
18014        lastWeek: function () {
18015            switch (this.day()) {
18016                case 0:
18017                    return '[prejšnjo] [nedeljo] [ob] LT';
18018                case 3:
18019                    return '[prejšnjo] [sredo] [ob] LT';
18020                case 6:
18021                    return '[prejšnjo] [soboto] [ob] LT';
18022                case 1:
18023                case 2:
18024                case 4:
18025                case 5:
18026                    return '[prejšnji] dddd [ob] LT';
18027            }
18028        },
18029        sameElse: 'L',
18030    },
18031    relativeTime: {
18032        future: 'čez %s',
18033        past: 'pred %s',
18034        s: processRelativeTime,
18035        ss: processRelativeTime,
18036        m: processRelativeTime,
18037        mm: processRelativeTime,
18038        h: processRelativeTime,
18039        hh: processRelativeTime,
18040        d: processRelativeTime,
18041        dd: processRelativeTime,
18042        M: processRelativeTime,
18043        MM: processRelativeTime,
18044        y: processRelativeTime,
18045        yy: processRelativeTime,
18046    },
18047    dayOfMonthOrdinalParse: /\d{1,2}\./,
18048    ordinal: '%d.',
18049    week: {
18050        dow: 1, // Monday is the first day of the week.
18051        doy: 7, // The week that contains Jan 7th is the first week of the year.
18052    },
18053}));
18054
18055
18056/***/ }),
18057/* 115 */
18058/***/ (function(module, __webpack_exports__, __webpack_require__) {
18059
18060"use strict";
18061Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
18062/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
18063//! moment.js locale configuration
18064//! locale : Albanian [sq]
18065//! author : Flakërim Ismani : https://github.com/flakerimi
18066//! author : Menelion Elensúle : https://github.com/Oire
18067//! author : Oerd Cukalla : https://github.com/oerd
18068
18069
18070
18071/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('sq', {
18072    months: 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split(
18073        '_'
18074    ),
18075    monthsShort: 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),
18076    weekdays: 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split(
18077        '_'
18078    ),
18079    weekdaysShort: 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),
18080    weekdaysMin: 'D_H_Ma_Më_E_P_Sh'.split('_'),
18081    weekdaysParseExact: true,
18082    meridiemParse: /PD|MD/,
18083    isPM: function (input) {
18084        return input.charAt(0) === 'M';
18085    },
18086    meridiem: function (hours, minutes, isLower) {
18087        return hours < 12 ? 'PD' : 'MD';
18088    },
18089    longDateFormat: {
18090        LT: 'HH:mm',
18091        LTS: 'HH:mm:ss',
18092        L: 'DD/MM/YYYY',
18093        LL: 'D MMMM YYYY',
18094        LLL: 'D MMMM YYYY HH:mm',
18095        LLLL: 'dddd, D MMMM YYYY HH:mm',
18096    },
18097    calendar: {
18098        sameDay: '[Sot në] LT',
18099        nextDay: '[Nesër në] LT',
18100        nextWeek: 'dddd [në] LT',
18101        lastDay: '[Dje në] LT',
18102        lastWeek: 'dddd [e kaluar në] LT',
18103        sameElse: 'L',
18104    },
18105    relativeTime: {
18106        future: 'në %s',
18107        past: '%s më parë',
18108        s: 'disa sekonda',
18109        ss: '%d sekonda',
vendor: 10,859 bytes, lines 18110-18432
18110        m: 'një minutë',
18111        mm: '%d minuta',
18112        h: 'një orë',
18113        hh: '%d orë',
18114        d: 'një ditë',
18115        dd: '%d ditë',
18116        M: 'një muaj',
18117        MM: '%d muaj',
18118        y: 'një vit',
18119        yy: '%d vite',
18120    },
18121    dayOfMonthOrdinalParse: /\d{1,2}\./,
18122    ordinal: '%d.',
18123    week: {
18124        dow: 1, // Monday is the first day of the week.
18125        doy: 4, // The week that contains Jan 4th is the first week of the year.
18126    },
18127}));
18128
18129
18130/***/ }),
18131/* 116 */
18132/***/ (function(module, __webpack_exports__, __webpack_require__) {
18133
18134"use strict";
18135Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
18136/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
18137//! moment.js locale configuration
18138//! locale : Serbian [sr]
18139//! author : Milan Janačković<[email protected]> : https://github.com/milan-j
18140//! author : Stefan Crnjaković <[email protected]> : https://github.com/crnjakovic
18141
18142
18143
18144var translator = {
18145    words: {
18146        //Different grammatical cases
18147        ss: ['sekunda', 'sekunde', 'sekundi'],
18148        m: ['jedan minut', 'jedne minute'],
18149        mm: ['minut', 'minute', 'minuta'],
18150        h: ['jedan sat', 'jednog sata'],
18151        hh: ['sat', 'sata', 'sati'],
18152        dd: ['dan', 'dana', 'dana'],
18153        MM: ['mesec', 'meseca', 'meseci'],
18154        yy: ['godina', 'godine', 'godina'],
18155    },
18156    correctGrammaticalCase: function (number, wordKey) {
18157        return number === 1
18158            ? wordKey[0]
18159            : number >= 2 && number <= 4
18160            ? wordKey[1]
18161            : wordKey[2];
18162    },
18163    translate: function (number, withoutSuffix, key) {
18164        var wordKey = translator.words[key];
18165        if (key.length === 1) {
18166            return withoutSuffix ? wordKey[0] : wordKey[1];
18167        } else {
18168            return (
18169                number +
18170                ' ' +
18171                translator.correctGrammaticalCase(number, wordKey)
18172            );
18173        }
18174    },
18175};
18176
18177/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('sr', {
18178    months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split(
18179        '_'
18180    ),
18181    monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split(
18182        '_'
18183    ),
18184    monthsParseExact: true,
18185    weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split(
18186        '_'
18187    ),
18188    weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'),
18189    weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'),
18190    weekdaysParseExact: true,
18191    longDateFormat: {
18192        LT: 'H:mm',
18193        LTS: 'H:mm:ss',
18194        L: 'D. M. YYYY.',
18195        LL: 'D. MMMM YYYY.',
18196        LLL: 'D. MMMM YYYY. H:mm',
18197        LLLL: 'dddd, D. MMMM YYYY. H:mm',
18198    },
18199    calendar: {
18200        sameDay: '[danas u] LT',
18201        nextDay: '[sutra u] LT',
18202        nextWeek: function () {
18203            switch (this.day()) {
18204                case 0:
18205                    return '[u] [nedelju] [u] LT';
18206                case 3:
18207                    return '[u] [sredu] [u] LT';
18208                case 6:
18209                    return '[u] [subotu] [u] LT';
18210                case 1:
18211                case 2:
18212                case 4:
18213                case 5:
18214                    return '[u] dddd [u] LT';
18215            }
18216        },
18217        lastDay: '[juče u] LT',
18218        lastWeek: function () {
18219            var lastWeekDays = [
18220                '[prošle] [nedelje] [u] LT',
18221                '[prošlog] [ponedeljka] [u] LT',
18222                '[prošlog] [utorka] [u] LT',
18223                '[prošle] [srede] [u] LT',
18224                '[prošlog] [četvrtka] [u] LT',
18225                '[prošlog] [petka] [u] LT',
18226                '[prošle] [subote] [u] LT',
18227            ];
18228            return lastWeekDays[this.day()];
18229        },
18230        sameElse: 'L',
18231    },
18232    relativeTime: {
18233        future: 'za %s',
18234        past: 'pre %s',
18235        s: 'nekoliko sekundi',
18236        ss: translator.translate,
18237        m: translator.translate,
18238        mm: translator.translate,
18239        h: translator.translate,
18240        hh: translator.translate,
18241        d: 'dan',
18242        dd: translator.translate,
18243        M: 'mesec',
18244        MM: translator.translate,
18245        y: 'godinu',
18246        yy: translator.translate,
18247    },
18248    dayOfMonthOrdinalParse: /\d{1,2}\./,
18249    ordinal: '%d.',
18250    week: {
18251        dow: 1, // Monday is the first day of the week.
18252        doy: 7, // The week that contains Jan 7th is the first week of the year.
18253    },
18254}));
18255
18256
18257/***/ }),
18258/* 117 */
18259/***/ (function(module, __webpack_exports__, __webpack_require__) {
18260
18261"use strict";
18262Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
18263/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
18264//! moment.js locale configuration
18265//! locale : Serbian Cyrillic [sr-cyrl]
18266//! author : Milan Janačković<[email protected]> : https://github.com/milan-j
18267//! author : Stefan Crnjaković <[email protected]> : https://github.com/crnjakovic
18268
18269
18270
18271var translator = {
18272    words: {
18273        //Different grammatical cases
18274        ss: ['секунда', 'секунде', 'секунди'],
18275        m: ['један минут', 'једне минуте'],
18276        mm: ['минут', 'минуте', 'минута'],
18277        h: ['један сат', 'једног сата'],
18278        hh: ['сат', 'сата', 'сати'],
18279        dd: ['дан', 'дана', 'дана'],
18280        MM: ['месец', 'месеца', 'месеци'],
18281        yy: ['година', 'године', 'година'],
18282    },
18283    correctGrammaticalCase: function (number, wordKey) {
18284        return number === 1
18285            ? wordKey[0]
18286            : number >= 2 && number <= 4
18287            ? wordKey[1]
18288            : wordKey[2];
18289    },
18290    translate: function (number, withoutSuffix, key) {
18291        var wordKey = translator.words[key];
18292        if (key.length === 1) {
18293            return withoutSuffix ? wordKey[0] : wordKey[1];
18294        } else {
18295            return (
18296                number +
18297                ' ' +
18298                translator.correctGrammaticalCase(number, wordKey)
18299            );
18300        }
18301    },
18302};
18303
18304/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('sr-cyrl', {
18305    months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split(
18306        '_'
18307    ),
18308    monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split(
18309        '_'
18310    ),
18311    monthsParseExact: true,
18312    weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'),
18313    weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'),
18314    weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'),
18315    weekdaysParseExact: true,
18316    longDateFormat: {
18317        LT: 'H:mm',
18318        LTS: 'H:mm:ss',
18319        L: 'D. M. YYYY.',
18320        LL: 'D. MMMM YYYY.',
18321        LLL: 'D. MMMM YYYY. H:mm',
18322        LLLL: 'dddd, D. MMMM YYYY. H:mm',
18323    },
18324    calendar: {
18325        sameDay: '[данас у] LT',
18326        nextDay: '[сутра у] LT',
18327        nextWeek: function () {
18328            switch (this.day()) {
18329                case 0:
18330                    return '[у] [недељу] [у] LT';
18331                case 3:
18332                    return '[у] [среду] [у] LT';
18333                case 6:
18334                    return '[у] [суботу] [у] LT';
18335                case 1:
18336                case 2:
18337                case 4:
18338                case 5:
18339                    return '[у] dddd [у] LT';
18340            }
18341        },
18342        lastDay: '[јуче у] LT',
18343        lastWeek: function () {
18344            var lastWeekDays = [
18345                '[прошле] [недеље] [у] LT',
18346                '[прошлог] [понедељка] [у] LT',
18347                '[прошлог] [уторка] [у] LT',
18348                '[прошле] [среде] [у] LT',
18349                '[прошлог] [четвртка] [у] LT',
18350                '[прошлог] [петка] [у] LT',
18351                '[прошле] [суботе] [у] LT',
18352            ];
18353            return lastWeekDays[this.day()];
18354        },
18355        sameElse: 'L',
18356    },
18357    relativeTime: {
18358        future: 'за %s',
18359        past: 'пре %s',
18360        s: 'неколико секунди',
18361        ss: translator.translate,
18362        m: translator.translate,
18363        mm: translator.translate,
18364        h: translator.translate,
18365        hh: translator.translate,
18366        d: 'дан',
18367        dd: translator.translate,
18368        M: 'месец',
18369        MM: translator.translate,
18370        y: 'годину',
18371        yy: translator.translate,
18372    },
18373    dayOfMonthOrdinalParse: /\d{1,2}\./,
18374    ordinal: '%d.',
18375    week: {
18376        dow: 1, // Monday is the first day of the week.
18377        doy: 7, // The week that contains Jan 1st is the first week of the year.
18378    },
18379}));
18380
18381
18382/***/ }),
18383/* 118 */
18384/***/ (function(module, __webpack_exports__, __webpack_require__) {
18385
18386"use strict";
18387Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
18388/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
18389//! moment.js locale configuration
18390//! locale : siSwati [ss]
18391//! author : Nicolai Davies<[email protected]> : https://github.com/nicolaidavies
18392
18393
18394
18395/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ss', {
18396    months: "Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split(
18397        '_'
18398    ),
18399    monthsShort: 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'),
18400    weekdays: 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split(
18401        '_'
18402    ),
18403    weekdaysShort: 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'),
18404    weekdaysMin: 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'),
18405    weekdaysParseExact: true,
18406    longDateFormat: {
18407        LT: 'h:mm A',
18408        LTS: 'h:mm:ss A',
18409        L: 'DD/MM/YYYY',
18410        LL: 'D MMMM YYYY',
18411        LLL: 'D MMMM YYYY h:mm A',
18412        LLLL: 'dddd, D MMMM YYYY h:mm A',
18413    },
18414    calendar: {
18415        sameDay: '[Namuhla nga] LT',
18416        nextDay: '[Kusasa nga] LT',
18417        nextWeek: 'dddd [nga] LT',
18418        lastDay: '[Itolo nga] LT',
18419        lastWeek: 'dddd [leliphelile] [nga] LT',
18420        sameElse: 'L',
18421    },
18422    relativeTime: {
18423        future: 'nga %s',
18424        past: 'wenteka nga %s',
18425        s: 'emizuzwana lomcane',
18426        ss: '%d mzuzwana',
18427        m: 'umzuzu',
18428        mm: '%d emizuzu',
18429        h: 'lihora',
18430        hh: '%d emahora',
18431        d: 'lilanga',
18432        dd: '%d emalanga',
18433        M: 'inyanga',
18434        MM: '%d tinyanga',
18435        y: 'umnyaka',
18436        yy: '%d iminyaka',
18437    },
18438    meridiemParse: /ekuseni|emini|entsambama|ebusuku/,
18439    meridiem: function (hours, minutes, isLower) {
18440        if (hours < 11) {
18441            return 'ekuseni';
18442        } else if (hours < 15) {
18443            return 'emini';
18444        } else if (hours < 19) {
18445            return 'entsambama';
18446        } else {
18447            return 'ebusuku';
18448        }
18449    },
18450    meridiemHour: function (hour, meridiem) {
18451        if (hour === 12) {
18452            hour = 0;
18453        }
18454        if (meridiem === 'ekuseni') {
18455            return hour;
18456        } else if (meridiem === 'emini') {
18457            return hour >= 11 ? hour : hour + 12;
18458        } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') {
18459            if (hour === 0) {
18460                return 0;
18461            }
18462            return hour + 12;
18463        }
18464    },
18465    dayOfMonthOrdinalParse: /\d{1,2}/,
18466    ordinal: '%d',
18467    week: {
18468        dow: 1, // Monday is the first day of the week.
18469        doy: 4, // The week that contains Jan 4th is the first week of the year.
18470    },
18471}));
18472
18473
18474/***/ }),
18475/* 119 */
18476/***/ (function(module, __webpack_exports__, __webpack_require__) {
18477
18478"use strict";
18479Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
18480/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
18481//! moment.js locale configuration
18482//! locale : Swedish [sv]
18483//! author : Jens Alm : https://github.com/ulmus
18484
18485
18486
18487/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('sv', {
18488    months: 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split(
18489        '_'
18490    ),
18491    monthsShort: 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
18492    weekdays: 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),
18493    weekdaysShort: 'sön_mån_tis_ons_tor_fre_lör'.split('_'),
18494    weekdaysMin: 'sö_må_ti_on_to_fr_lö'.split('_'),
18495    longDateFormat: {
18496        LT: 'HH:mm',
18497        LTS: 'HH:mm:ss',
18498        L: 'YYYY-MM-DD',
18499        LL: 'D MMMM YYYY',
18500        LLL: 'D MMMM YYYY [kl.] HH:mm',
18501        LLLL: 'dddd D MMMM YYYY [kl.] HH:mm',
18502        lll: 'D MMM YYYY HH:mm',
18503        llll: 'ddd D MMM YYYY HH:mm',
18504    },
18505    calendar: {
18506        sameDay: '[Idag] LT',
18507        nextDay: '[Imorgon] LT',
18508        lastDay: '[Igår] LT',
18509        nextWeek: '[PÃ¥] dddd LT',
18510        lastWeek: '[I] dddd[s] LT',
18511        sameElse: 'L',
18512    },
18513    relativeTime: {
18514        future: 'om %s',
18515        past: 'för %s sedan',
18516        s: 'några sekunder',
18517        ss: '%d sekunder',
18518        m: 'en minut',
18519        mm: '%d minuter',
18520        h: 'en timme',
18521        hh: '%d timmar',
18522        d: 'en dag',
18523        dd: '%d dagar',
18524        M: 'en månad',
18525        MM: '%d månader',
18526        y: 'ett år',
18527        yy: '%d år',
18528    },
18529    dayOfMonthOrdinalParse: /\d{1,2}(\:e|\:a)/,
18530    ordinal: function (number) {
18531        var b = number % 10,
18532            output =
18533                ~~((number % 100) / 10) === 1
18534                    ? ':e'
18535                    : b === 1
18536                    ? ':a'
18537                    : b === 2
18538                    ? ':a'
18539                    : b === 3
18540                    ? ':e'
18541                    : ':e';
18542        return number + output;
18543    },
18544    week: {
18545        dow: 1, // Monday is the first day of the week.
18546        doy: 4, // The week that contains Jan 4th is the first week of the year.
18547    },
18548}));
18549
18550
18551/***/ }),
18552/* 120 */
18553/***/ (function(module, __webpack_exports__, __webpack_require__) {
18554
18555"use strict";
18556Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
18557/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
18558//! moment.js locale configuration
18559//! locale : Swahili [sw]
18560//! author : Fahad Kassim : https://github.com/fadsel
18561
18562
18563
18564/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('sw', {
18565    months: 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split(
18566        '_'
18567    ),
18568    monthsShort: 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'),
18569    weekdays: 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split(
18570        '_'
18571    ),
18572    weekdaysShort: 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'),
18573    weekdaysMin: 'J2_J3_J4_J5_Al_Ij_J1'.split('_'),
18574    weekdaysParseExact: true,
18575    longDateFormat: {
18576        LT: 'hh:mm A',
18577        LTS: 'HH:mm:ss',
18578        L: 'DD.MM.YYYY',
18579        LL: 'D MMMM YYYY',
18580        LLL: 'D MMMM YYYY HH:mm',
18581        LLLL: 'dddd, D MMMM YYYY HH:mm',
18582    },
18583    calendar: {
18584        sameDay: '[leo saa] LT',
18585        nextDay: '[kesho saa] LT',
18586        nextWeek: '[wiki ijayo] dddd [saat] LT',
18587        lastDay: '[jana] LT',
18588        lastWeek: '[wiki iliyopita] dddd [saat] LT',
18589        sameElse: 'L',
18590    },
18591    relativeTime: {
18592        future: '%s baadaye',
18593        past: 'tokea %s',
18594        s: 'hivi punde',
18595        ss: 'sekunde %d',
18596        m: 'dakika moja',
18597        mm: 'dakika %d',
18598        h: 'saa limoja',
18599        hh: 'masaa %d',
18600        d: 'siku moja',
18601        dd: 'siku %d',
18602        M: 'mwezi mmoja',
18603        MM: 'miezi %d',
18604        y: 'mwaka mmoja',
18605        yy: 'miaka %d',
18606    },
18607    week: {
18608        dow: 1, // Monday is the first day of the week.
18609        doy: 7, // The week that contains Jan 7th is the first week of the year.
18610    },
18611}));
18612
18613
18614/***/ }),
18615/* 121 */
18616/***/ (function(module, __webpack_exports__, __webpack_require__) {
18617
18618"use strict";
18619Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
18620/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
18621//! moment.js locale configuration
18622//! locale : Tamil [ta]
18623//! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404
18624
18625
18626
18627var symbolMap = {
18628        1: '௧',
18629        2: '௨',
18630        3: '௩',
18631        4: '௪',
18632        5: '௫',
18633        6: '௬',
18634        7: '௭',
18635        8: '௮',
18636        9: '௯',
18637        0: '௦',
18638    },
18639    numberMap = {
18640        '௧': '1',
18641        '௨': '2',
18642        '௩': '3',
18643        '௪': '4',
18644        '௫': '5',
18645        '௬': '6',
18646        '௭': '7',
18647        '௮': '8',
18648        '௯': '9',
18649        '௦': '0',
18650    };
18651
18652/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ta', {
18653    months: 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்ப
vendor: 6,451 bytes, lines 18653-18810
18653ர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split(
18654        '_'
18655    ),
18656    monthsShort: 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split(
18657        '_'
18658    ),
18659    weekdays: 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split(
18660        '_'
18661    ),
18662    weekdaysShort: 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split(
18663        '_'
18664    ),
18665    weekdaysMin: 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),
18666    longDateFormat: {
18667        LT: 'HH:mm',
18668        LTS: 'HH:mm:ss',
18669        L: 'DD/MM/YYYY',
18670        LL: 'D MMMM YYYY',
18671        LLL: 'D MMMM YYYY, HH:mm',
18672        LLLL: 'dddd, D MMMM YYYY, HH:mm',
18673    },
18674    calendar: {
18675        sameDay: '[இன்று] LT',
18676        nextDay: '[நாளை] LT',
18677        nextWeek: 'dddd, LT',
18678        lastDay: '[நேற்று] LT',
18679        lastWeek: '[கடந்த வாரம்] dddd, LT',
18680        sameElse: 'L',
18681    },
18682    relativeTime: {
18683        future: '%s இல்',
18684        past: '%s முன்',
18685        s: 'ஒரு சில விநாடிகள்',
18686        ss: '%d விநாடிகள்',
18687        m: 'ஒரு நிமிடம்',
18688        mm: '%d நிமிடங்கள்',
18689        h: 'ஒரு மணி நேரம்',
18690        hh: '%d மணி நேரம்',
18691        d: 'ஒரு நாள்',
18692        dd: '%d நாட்கள்',
18693        M: 'ஒரு மாதம்',
18694        MM: '%d மாதங்கள்',
18695        y: 'ஒரு வருடம்',
18696        yy: '%d ஆண்டுகள்',
18697    },
18698    dayOfMonthOrdinalParse: /\d{1,2}வது/,
18699    ordinal: function (number) {
18700        return number + 'வது';
18701    },
18702    preparse: function (string) {
18703        return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) {
18704            return numberMap[match];
18705        });
18706    },
18707    postformat: function (string) {
18708        return string.replace(/\d/g, function (match) {
18709            return symbolMap[match];
18710        });
18711    },
18712    // refer http://ta.wikipedia.org/s/1er1
18713    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,
18714    meridiem: function (hour, minute, isLower) {
18715        if (hour < 2) {
18716            return ' யாமம்';
18717        } else if (hour < 6) {
18718            return ' வைகறை'; // வைகறை
18719        } else if (hour < 10) {
18720            return ' காலை'; // காலை
18721        } else if (hour < 14) {
18722            return ' நண்பகல்'; // நண்பகல்
18723        } else if (hour < 18) {
18724            return ' எற்பாடு'; // எற்பாடு
18725        } else if (hour < 22) {
18726            return ' மாலை'; // மாலை
18727        } else {
18728            return ' யாமம்';
18729        }
18730    },
18731    meridiemHour: function (hour, meridiem) {
18732        if (hour === 12) {
18733            hour = 0;
18734        }
18735        if (meridiem === 'யாமம்') {
18736            return hour < 2 ? hour : hour + 12;
18737        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {
18738            return hour;
18739        } else if (meridiem === 'நண்பகல்') {
18740            return hour >= 10 ? hour : hour + 12;
18741        } else {
18742            return hour + 12;
18743        }
18744    },
18745    week: {
18746        dow: 0, // Sunday is the first day of the week.
18747        doy: 6, // The week that contains Jan 6th is the first week of the year.
18748    },
18749}));
18750
18751
18752/***/ }),
18753/* 122 */
18754/***/ (function(module, __webpack_exports__, __webpack_require__) {
18755
18756"use strict";
18757Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
18758/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
18759//! moment.js locale configuration
18760//! locale : Telugu [te]
18761//! author : Krishna Chaitanya Thota : https://github.com/kcthota
18762
18763
18764
18765/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('te', {
18766    months: 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జులై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split(
18767        '_'
18768    ),
18769    monthsShort: 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జులై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split(
18770        '_'
18771    ),
18772    monthsParseExact: true,
18773    weekdays: 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split(
18774        '_'
18775    ),
18776    weekdaysShort: 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'),
18777    weekdaysMin: 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'),
18778    longDateFormat: {
18779        LT: 'A h:mm',
18780        LTS: 'A h:mm:ss',
18781        L: 'DD/MM/YYYY',
18782        LL: 'D MMMM YYYY',
18783        LLL: 'D MMMM YYYY, A h:mm',
18784        LLLL: 'dddd, D MMMM YYYY, A h:mm',
18785    },
18786    calendar: {
18787        sameDay: '[నేడు] LT',
18788        nextDay: '[రేపు] LT',
18789        nextWeek: 'dddd, LT',
18790        lastDay: '[నిన్న] LT',
18791        lastWeek: '[గత] dddd, LT',
18792        sameElse: 'L',
18793    },
18794    relativeTime: {
18795        future: '%s లో',
18796        past: '%s క్రితం',
18797        s: 'కొన్ని క్షణాలు',
18798        ss: '%d సెకన్లు',
18799        m: 'ఒక నిమిషం',
18800        mm: '%d నిమిషాలు',
18801        h: 'ఒక గంట',
18802        hh: '%d గంటలు',
18803        d: 'ఒక రోజు',
18804        dd: '%d రోజులు',
18805        M: 'ఒక నెల',
18806        MM: '%d నెలలు',
18807        y: 'ఒక సంవత్సరం',
18808        yy: '%d సంవత్సరాలు',
18809    },
18810    dayOfMonthOrdinalParse: /\d{1,2}à°µ/,
18811    ordinal: '%dà°µ',
18812    meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,
18813    meridiemHour: function (hour, meridiem) {
18814        if (hour === 12) {
18815            hour = 0;
18816        }
18817        if (meridiem === 'రాత్రి') {
18818            return hour < 4 ? hour : hour + 12;
18819        } else if (meridiem === 'ఉదయం') {
18820            return hour;
18821        } else if (meridiem === 'మధ్యాహ్నం') {
18822            return hour >= 10 ? hour : hour + 12;
18823        } else if (meridiem === 'సాయంత్రం') {
18824            return hour + 12;
18825        }
18826    },
18827    meridiem: function (hour, minute, isLower) {
18828        if (hour < 4) {
18829            return 'రాత్రి';
18830        } else if (hour < 10) {
18831            return 'ఉదయం';
18832        } else if (hour < 17) {
18833            return 'మధ్యాహ్నం';
18834        } else if (hour < 20) {
18835            return 'సాయంత్రం';
18836        } else {
18837            return 'రాత్రి';
18838        }
18839    },
18840    week: {
18841        dow: 0, // Sunday is the first day of the week.
18842        doy: 6, // The week that contains Jan 6th is the first week of the year.
18843    },
18844}));
18845
18846
18847/***/ }),
18848/* 123 */
18849/***/ (function(module, __webpack_exports__, __webpack_require__) {
18850
18851"use strict";
18852Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
18853/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
18854//! moment.js locale configuration
18855//! locale : Tetun Dili (East Timor) [tet]
18856//! author : Joshua Brooks : https://github.com/joshbrooks
18857//! author : Onorio De J. Afonso : https://github.com/marobo
18858//! author : Sonia Simoes : https://github.com/soniasimoes
18859
18860
18861
18862/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('tet', {
18863    months: 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juñu_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru'.split(
18864        '_'
18865    ),
18866    monthsShort: 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),
18867    weekdays: 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu'.split('_'),
18868    weekdaysShort: 'Dom_Seg_Ters_Kua_Kint_Sest_Sab'.split('_'),
18869    weekdaysMin: 'Do_Seg_Te_Ku_Ki_Ses_Sa'.split('_'),
18870    longDateFormat: {
18871        LT: 'HH:mm',
18872        LTS: 'HH:mm:ss',
18873        L: 'DD/MM/YYYY',
18874        LL: 'D MMMM YYYY',
18875        LLL: 'D MMMM YYYY HH:mm',
18876        LLLL: 'dddd, D MMMM YYYY HH:mm',
18877    },
18878    calendar: {
18879        sameDay: '[Ohin iha] LT',
18880        nextDay: '[Aban iha] LT',
18881        nextWeek: 'dddd [iha] LT',
18882        lastDay: '[Horiseik iha] LT',
18883        lastWeek: 'dddd [semana kotuk] [iha] LT',
18884        sameElse: 'L',
18885    },
18886    relativeTime: {
18887        future: 'iha %s',
18888        past: '%s liuba',
18889        s: 'segundu balun',
18890        ss: 'segundu %d',
18891        m: 'minutu ida',
18892        mm: 'minutu %d',
18893        h: 'oras ida',
18894        hh: 'oras %d',
18895        d: 'loron ida',
18896        dd: 'loron %d',
18897        M: 'fulan ida',
18898        MM: 'fulan %d',
18899        y: 'tinan ida',
18900        yy: 'tinan %d',
18901    },
18902    dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/,
18903    ordinal: function (number) {
18904        var b = number % 10,
18905            output =
18906                ~~((number % 100) / 10) === 1
18907                    ? 'th'
18908                    : b === 1
18909                    ? 'st'
18910                    : b === 2
18911                    ? 'nd'
18912                    : b === 3
18913                    ? 'rd'
18914                    : 'th';
18915        return number + output;
18916    },
18917    week: {
18918        dow: 1, // Monday is the first day of the week.
18919        doy: 4, // The week that contains Jan 4th is the first week of the year.
18920    },
18921}));
18922
18923
18924/***/ }),
18925/* 124 */
18926/***/ (function(module, __webpack_exports__, __webpack_require__) {
18927
18928"use strict";
18929Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
18930/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
18931//! moment.js locale configuration
18932//! locale : Tajik [tg]
18933//! author : Orif N. Jr. : https://github.com/orif-jr
18934
18935
18936
18937var suffixes = {
18938    0: '-ум',
18939    1: '-ум',
18940    2: '-юм',
18941    3: '-юм',
18942    4: '-ум',
18943    5: '-ум',
18944    6: '-ум',
18945    7: '-ум',
18946    8: '-ум',
18947    9: '-ум',
18948    10: '-ум',
18949    12: '-ум',
18950    13: '-ум',
18951    20: '-ум',
18952    30: '-юм',
18953    40: '-ум',
18954    50: '-ум',
18955    60: '-ум',
18956    70: '-ум',
18957    80: '-ум',
18958    90: '-ум',
18959    100: '-ум',
18960};
18961
18962/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('tg', {
18963    months: {
18964        format: 'январи_феврали_марти_апрели_майи_июни_июли_августи_сентябри_октябри_ноябри_декабри'.split(
18965            '_'
18966        ),
18967        standalone: 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split(
18968            '_'
18969        ),
18970    },
18971    monthsShort: 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),
18972    weekdays: 'якшанбе_душанбе_сешанбе_чоршанбе_панҷшанбе_ҷумъа_шанбе'.split(
18973        '_'
18974    ),
18975    weekdaysShort: 'яшб_дшб_сшб_чшб_пшб_ҷум_шнб'.split('_'),
18976    weekdaysMin: 'яш_дш_сш_чш_пш_ҷм_шб'.split('_'),
18977    longDateFormat: {
18978        LT: 'HH:mm',
18979        LTS: 'HH:mm:ss',
18980        L: 'DD.MM.YYYY',
18981        LL: 'D MMMM YYYY',
18982        LLL: 'D MMMM YYYY HH:mm',
18983        LLLL: 'dddd, D MMMM YYYY HH:mm',
18984    },
18985    calendar: {
18986        sameDay: '[Имрӯз соати] LT',
18987        nextDay: '[Фардо соати] LT',
18988        lastDay: '[Дирӯз соати] LT',
18989        nextWeek: 'dddd[и] [ҳафтаи оянда соати] LT',
18990        lastWeek: 'dddd[и] [ҳафтаи гузашта соати] LT',
18991        sameElse: 'L',
18992    },
18993    relativeTime: {
18994        future: 'баъди %s',
18995        past: '%s пеш',
18996        s: 'якчанд сония',
18997        m: 'як дақиқа',
18998        mm: '%d дақиқа',
18999        h: 'як соат',
19000        hh: '%d соат',
19001        d: 'як рӯз',
19002        dd: '%d рӯз',
19003        M: 'як моҳ',
19004        MM: '%d моҳ',
19005        y: 'як сол',
19006        yy: '%d сол',
19007    },
19008    meridiemParse: /шаб|субҳ|рӯз|бегоҳ/,
19009    meridiemHour: function (hour, meridiem) {
19010        if (hour === 12) {
19011            hour = 0;
19012        }
19013        if (meridiem === 'шаб') {
19014            return hour < 4 ? hour : hour + 12;
19015        } else if (meridiem === 'субҳ') {
19016            return hour;
19017        } else if (meridiem === 'рӯз') {
19018            return hour >= 11 ? hour : hour + 12;
19019        } else if (meridiem === 'бегоҳ') {
19020            return hour + 12;
19021        }
19022    },
19023    meridiem: function (hour, minute, isLower) {
19024        if (hour < 4) {
19025            return 'шаб';
19026        } else if (hour < 11) {
19027            return 'субҳ';
19028        } else if (hour < 16) {
19029            return 'рӯз';
19030        } else if (hour < 19) {
19031            return 'бегоҳ';
19032        } else {
19033            return 'шаб';
19034        }
19035    },
19036    dayOfMonthOrdinalParse: /\d{1,2}-(ум|юм)/,
19037    ordinal: function (number) {
19038        var a = number % 10,
19039            b = number >= 100 ? 100 : null;
19040        return number + (suffixes[number] || suffixes[a] || suffixes[b]);
19041    },
19042    week: {
19043        dow: 1, // Monday is the first day of the week.
19044        doy: 7, // The week that contains Jan 1th is the first week of the year.
19045    },
19046}));
19047
19048
19049/***/ }),
19050/* 125 */
19051/***/ (function(module, __webpack_exports__, __webpack_require__) {
19052
19053"use strict";
19054Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
19055/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
19056//! moment.js locale configuration
19057//! locale : Thai [th]
19058//! author : Kridsada Thanabulpong : https://github.com/sirn
19059
19060
19061
19062/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('th', {
19063    months: 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split(
19064        '_'
19065    ),
19066    monthsShort: 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split(
19067        '_'
19068    ),
19069    monthsParseExact: true,
19070    weekdays: 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.
vendor: 6,411 bytes, lines 19070-19271
19070split('_'),
19071    weekdaysShort: 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference
19072    weekdaysMin: 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),
19073    weekdaysParseExact: true,
19074    longDateFormat: {
19075        LT: 'H:mm',
19076        LTS: 'H:mm:ss',
19077        L: 'DD/MM/YYYY',
19078        LL: 'D MMMM YYYY',
19079        LLL: 'D MMMM YYYY เวลา H:mm',
19080        LLLL: 'วันddddที่ D MMMM YYYY เวลา H:mm',
19081    },
19082    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,
19083    isPM: function (input) {
19084        return input === 'หลังเที่ยง';
19085    },
19086    meridiem: function (hour, minute, isLower) {
19087        if (hour < 12) {
19088            return 'ก่อนเที่ยง';
19089        } else {
19090            return 'หลังเที่ยง';
19091        }
19092    },
19093    calendar: {
19094        sameDay: '[วันนี้ เวลา] LT',
19095        nextDay: '[พรุ่งนี้ เวลา] LT',
19096        nextWeek: 'dddd[หน้า เวลา] LT',
19097        lastDay: '[เมื่อวานนี้ เวลา] LT',
19098        lastWeek: '[วัน]dddd[ที่แล้ว เวลา] LT',
19099        sameElse: 'L',
19100    },
19101    relativeTime: {
19102        future: 'อีก %s',
19103        past: '%sที่แล้ว',
19104        s: 'ไม่กี่วินาที',
19105        ss: '%d วินาที',
19106        m: '1 นาที',
19107        mm: '%d นาที',
19108        h: '1 ชั่วโมง',
19109        hh: '%d ชั่วโมง',
19110        d: '1 วัน',
19111        dd: '%d วัน',
19112        w: '1 สัปดาห์',
19113        ww: '%d สัปดาห์',
19114        M: '1 เดือน',
19115        MM: '%d เดือน',
19116        y: '1 ปี',
19117        yy: '%d ปี',
19118    },
19119}));
19120
19121
19122/***/ }),
19123/* 126 */
19124/***/ (function(module, __webpack_exports__, __webpack_require__) {
19125
19126"use strict";
19127Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
19128/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
19129//! moment.js locale configuration
19130//! locale : Turkmen [tk]
19131//! author : Atamyrat Abdyrahmanov : https://github.com/atamyratabdy
19132
19133
19134
19135var suffixes = {
19136    1: "'inji",
19137    5: "'inji",
19138    8: "'inji",
19139    70: "'inji",
19140    80: "'inji",
19141    2: "'nji",
19142    7: "'nji",
19143    20: "'nji",
19144    50: "'nji",
19145    3: "'ünji",
19146    4: "'ünji",
19147    100: "'ünji",
19148    6: "'njy",
19149    9: "'unjy",
19150    10: "'unjy",
19151    30: "'unjy",
19152    60: "'ynjy",
19153    90: "'ynjy",
19154};
19155
19156/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('tk', {
19157    months: 'Ýanwar_Fewral_Mart_Aprel_Maý_Iýun_Iýul_Awgust_Sentýabr_Oktýabr_Noýabr_Dekabr'.split(
19158        '_'
19159    ),
19160    monthsShort: 'Ýan_Few_Mar_Apr_Maý_Iýn_Iýl_Awg_Sen_Okt_Noý_Dek'.split('_'),
19161    weekdays: 'Ýekşenbe_Duşenbe_Sişenbe_Çarşenbe_Penşenbe_Anna_Şenbe'.split(
19162        '_'
19163    ),
19164    weekdaysShort: 'Ýek_Duş_Siş_Çar_Pen_Ann_Şen'.split('_'),
19165    weekdaysMin: 'Ýk_Dş_Sş_Çr_Pn_An_Şn'.split('_'),
19166    longDateFormat: {
19167        LT: 'HH:mm',
19168        LTS: 'HH:mm:ss',
19169        L: 'DD.MM.YYYY',
19170        LL: 'D MMMM YYYY',
19171        LLL: 'D MMMM YYYY HH:mm',
19172        LLLL: 'dddd, D MMMM YYYY HH:mm',
19173    },
19174    calendar: {
19175        sameDay: '[bugün sagat] LT',
19176        nextDay: '[ertir sagat] LT',
19177        nextWeek: '[indiki] dddd [sagat] LT',
19178        lastDay: '[düýn] LT',
19179        lastWeek: '[geçen] dddd [sagat] LT',
19180        sameElse: 'L',
19181    },
19182    relativeTime: {
19183        future: '%s soň',
19184        past: '%s öň',
19185        s: 'birnäçe sekunt',
19186        m: 'bir minut',
19187        mm: '%d minut',
19188        h: 'bir sagat',
19189        hh: '%d sagat',
19190        d: 'bir gün',
19191        dd: '%d gün',
19192        M: 'bir aý',
19193        MM: '%d aý',
19194        y: 'bir ýyl',
19195        yy: '%d ýyl',
19196    },
19197    ordinal: function (number, period) {
19198        switch (period) {
19199            case 'd':
19200            case 'D':
19201            case 'Do':
19202            case 'DD':
19203                return number;
19204            default:
19205                if (number === 0) {
19206                    // special case for zero
19207                    return number + "'unjy";
19208                }
19209                var a = number % 10,
19210                    b = (number % 100) - a,
19211                    c = number >= 100 ? 100 : null;
19212                return number + (suffixes[a] || suffixes[b] || suffixes[c]);
19213        }
19214    },
19215    week: {
19216        dow: 1, // Monday is the first day of the week.
19217        doy: 7, // The week that contains Jan 7th is the first week of the year.
19218    },
19219}));
19220
19221
19222/***/ }),
19223/* 127 */
19224/***/ (function(module, __webpack_exports__, __webpack_require__) {
19225
19226"use strict";
19227Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
19228/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
19229//! moment.js locale configuration
19230//! locale : Tagalog (Philippines) [tl-ph]
19231//! author : Dan Hagman : https://github.com/hagmandan
19232
19233
19234
19235/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('tl-ph', {
19236    months: 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split(
19237        '_'
19238    ),
19239    monthsShort: 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),
19240    weekdays: 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split(
19241        '_'
19242    ),
19243    weekdaysShort: 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),
19244    weekdaysMin: 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),
19245    longDateFormat: {
19246        LT: 'HH:mm',
19247        LTS: 'HH:mm:ss',
19248        L: 'MM/D/YYYY',
19249        LL: 'MMMM D, YYYY',
19250        LLL: 'MMMM D, YYYY HH:mm',
19251        LLLL: 'dddd, MMMM DD, YYYY HH:mm',
19252    },
19253    calendar: {
19254        sameDay: 'LT [ngayong araw]',
19255        nextDay: '[Bukas ng] LT',
19256        nextWeek: 'LT [sa susunod na] dddd',
19257        lastDay: 'LT [kahapon]',
19258        lastWeek: 'LT [noong nakaraang] dddd',
19259        sameElse: 'L',
19260    },
19261    relativeTime: {
19262        future: 'sa loob ng %s',
19263        past: '%s ang nakalipas',
19264        s: 'ilang segundo',
19265        ss: '%d segundo',
19266        m: 'isang minuto',
19267        mm: '%d minuto',
19268        h: 'isang oras',
19269        hh: '%d oras',
19270        d: 'isang araw',
19271        dd: '%d araw',
19272        M: 'isang buwan',
19273        MM: '%d buwan',
19274        y: 'isang taon',
19275        yy: '%d taon',
19276    },
19277    dayOfMonthOrdinalParse: /\d{1,2}/,
19278    ordinal: function (number) {
19279        return number;
19280    },
19281    week: {
19282        dow: 1, // Monday is the first day of the week.
19283        doy: 4, // The week that contains Jan 4th is the first week of the year.
19284    },
19285}));
19286
19287
19288/***/ }),
19289/* 128 */
19290/***/ (function(module, __webpack_exports__, __webpack_require__) {
19291
19292"use strict";
19293Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
19294/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
19295//! moment.js locale configuration
19296//! locale : Klingon [tlh]
19297//! author : Dominika Kruk : https://github.com/amaranthrose
19298
19299
19300
19301var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_');
19302
19303function translateFuture(output) {
19304    var time = output;
19305    time =
19306        output.indexOf('jaj') !== -1
19307            ? time.slice(0, -3) + 'leS'
19308            : output.indexOf('jar') !== -1
19309            ? time.slice(0, -3) + 'waQ'
19310            : output.indexOf('DIS') !== -1
19311            ? time.slice(0, -3) + 'nem'
19312            : time + ' pIq';
19313    return time;
19314}
19315
19316function translatePast(output) {
19317    var time = output;
19318    time =
19319        output.indexOf('jaj') !== -1
19320            ? time.slice(0, -3) + 'Hu’'
19321            : output.indexOf('jar') !== -1
19322            ? time.slice(0, -3) + 'wen'
19323            : output.indexOf('DIS') !== -1
19324            ? time.slice(0, -3) + 'ben'
19325            : time + ' ret';
19326    return time;
19327}
19328
19329function translate(number, withoutSuffix, string, isFuture) {
19330    var numberNoun = numberAsNoun(number);
19331    switch (string) {
19332        case 'ss':
19333            return numberNoun + ' lup';
19334        case 'mm':
19335            return numberNoun + ' tup';
19336        case 'hh':
19337            return numberNoun + ' rep';
19338        case 'dd':
19339            return numberNoun + ' jaj';
19340        case 'MM':
19341            return numberNoun + ' jar';
19342        case 'yy':
19343            return numberNoun + ' DIS';
19344    }
19345}
19346
19347function numberAsNoun(number) {
19348    var hundred = Math.floor((number % 1000) / 100),
19349        ten = Math.floor((number % 100) / 10),
19350        one = number % 10,
19351        word = '';
19352    if (hundred > 0) {
19353        word += numbersNouns[hundred] + 'vatlh';
19354    }
19355    if (ten > 0) {
19356        word += (word !== '' ? ' ' : '') + numbersNouns[ten] + 'maH';
19357    }
19358    if (one > 0) {
19359        word += (word !== '' ? ' ' : '') + numbersNouns[one];
19360    }
19361    return word === '' ? 'pagh' : word;
19362}
19363
19364/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('tlh', {
19365    months: 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split(
19366        '_'
19367    ),
19368    monthsShort: 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split(
19369        '_'
19370    ),
19371    monthsParseExact: true,
19372    weekdays: 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split(
19373        '_'
19374    ),
19375    weekdaysShort: 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split(
19376        '_'
19377    ),
19378    weekdaysMin: 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split(
19379        '_'
19380    ),
19381    longDateFormat: {
19382        LT: 'HH:mm',
19383        LTS: 'HH:mm:ss',
19384        L: 'DD.MM.YYYY',
19385        LL: 'D MMMM YYYY',
19386        LLL: 'D MMMM YYYY HH:mm',
19387        LLLL: 'dddd, D MMMM YYYY HH:mm',
19388    },
19389    calendar: {
19390        sameDay: '[DaHjaj] LT',
19391        nextDay: '[wa’leS] LT',
19392        nextWeek: 'LLL',
19393        lastDay: '[wa’Hu’] LT',
19394        lastWeek: 'LLL',
19395        sameElse: 'L',
19396    },
19397    relativeTime: {
19398        future: translateFuture,
19399        past: translatePast,
19400        s: 'puS lup',
19401        ss: translate,
19402        m: 'wa’ tup',
19403        mm: translate,
19404        h: 'wa’ rep',
19405        hh: translate,
19406        d: 'wa’ jaj',
19407        dd: translate,
19408        M: 'wa’ jar',
19409        MM: translate,
19410        y: 'wa’ DIS',
19411        yy: translate,
19412    },
19413    dayOfMonthOrdinalParse: /\d{1,2}\./,
19414    ordinal: '%d.',
19415    week: {
19416        dow: 1, // Monday is the first day of the week.
19417        doy: 4, // The week that contains Jan 4th is the first week of the year.
19418    },
19419}));
19420
19421
19422/***/ }),
19423/* 129 */
19424/***/ (function(module, __webpack_exports__, __webpack_require__) {
19425
19426"use strict";
19427Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
19428/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
19429//! moment.js locale configuration
19430//! locale : Turkish [tr]
19431//! authors : Erhan Gundogan : https://github.com/erhangundogan,
19432//!           Burak Yiğit Kaya: https://github.com/BYK
19433
19434
19435
19436var suffixes = {
19437    1: "'inci",
19438    5: "'inci",
19439    8: "'inci",
19440    70: "'inci",
19441    80: "'inci",
19442    2: "'nci",
19443    7: "'nci",
19444    20: "'nci",
19445    50: "'nci",
19446    3: "'üncü",
19447    4: "'üncü",
19448    100: "'üncü",
19449    6: "'ncı",
19450    9: "'uncu",
19451    10: "'uncu",
19452    30: "'uncu",
19453    60: "'ıncı",
19454    90: "'ıncı",
19455};
19456
19457/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('tr', {
19458    months: 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split(
19459        '_'
19460    ),
19461    monthsShort: 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),
19462    weekdays: 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split(
19463        '_'
19464    ),
19465    weekdaysShort: 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),
19466    weekdaysMin: 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
19467    meridiem: function (hours, minutes, isLower) {
19468        if (hours < 12) {
19469            return isLower ? 'öö' : 'ÖÖ';
19470        } else {
19471            return isLower ? 'ös' : 'ÖS';
19472        }
19473    },
19474    meridiemParse: /öö|ÖÖ|ös|ÖS/,
19475    isPM: function (input) {
19476        return input === 'ös' || input === 'ÖS';
19477    },
19478    longDateFormat: {
19479        LT: 'HH:mm',
19480        LTS: 'HH:mm:ss',
19481        L: 'DD.MM.YYYY',
19482        LL: 'D MMMM YYYY',
19483        LLL: 'D MMMM YYYY HH:mm',
19484        LLLL: 'dddd, D MMMM YYYY HH:mm',
19485    },
19486    calendar: {
19487        sameDay: '[bugün saat] LT',
19488        nextDay: '[yarın saat] LT',
19489        nextWeek: '[gelecek] dddd [saat] LT',
19490        lastDay: '[dün] LT',
19491        lastWeek: '[geçen] dddd [saat] LT',
19492        sameElse: 'L',
19493    },
19494    relativeTime: {
19495        future: '%s sonra',
19496        past: '%s önce',
19497        s: 'birkaç saniye',
19498        ss: '%d saniye',
19499        m: 'bir dakika',
19500        mm: '%d dakika',
19501        h: 'bir saat',
19502        hh: '%d saat',
19503        d: 'bir gün',
19504        dd: '%d gün',
19505        w: 'bir hafta',
19506        ww: '%d hafta',
19507        M: 'bir ay',
19508        MM: '%d ay',
19509        y: 'bir yıl',
19510        yy: '%d yıl',
19511    },
19512    ordinal: function (number, period) {
19513        switch (period) {
19514            case 'd':
19515            case 'D':
19516            case 'Do':
19517            case 'DD':
19518                return number;
19519            default:
19520                if (number === 0) {
19521                    // special case for zero
19522                    return number + "'ıncı";
19523                }
19524                var a = number % 10,
19525                    b = (number % 100) - a,
19526                    c = number >= 100 ? 100 : null;
19527                return number + (suffixes[a] || suffixes[b] || suffixes[c]);
19528        }
19529    },
19530    week: {
19531        dow: 1, // Monday is the first day of the week.
19532        doy: 7, // The week that contains Jan 7th is the first week of the year.
19533    },
19534}));
19535
19536
19537/***/ }),
19538/* 130 */
19539/***/ (function(module, __webpack_exports__, __webpack_require__) {
19540
19541"use strict";
19542Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
19543/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
19544//! moment.js locale configuration
19545//! locale : Talossan [tzl]
19546//! author : Robin van der Vliet : https://github.com/robin0van0der0v
19547//! author : Iustì Canun
19548
19549
19550
19551// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.
19552// This is currently too difficult (maybe even impossible) to add.
19553/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('tzl', {
19554    months: 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split(
19555        '_'
19556    ),
19557    monthsShort: 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),
19558    weekdays: 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),
19559    weekdaysShort: 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),
19560    weekdaysMin: 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),
19561    longDateFormat: {
19562        LT: 'HH.mm',
19563        LTS: 'HH.mm.ss',
19564        L: 'DD.MM.YYYY',
19565        LL: 'D. MMMM [dallas] YYYY',
19566        LLL: 'D. MMMM [dallas] YYYY HH.mm',
19567        LLLL: 'dddd, [li] D. MMMM [dallas] YYYY HH.mm',
19568    },
19569    meridiemParse: /d\'o|d\'a/i,
19570    isPM: function (input) {
19571        return "d'o" === input.toLowerCase();
19572    },
19573    meridiem: function (hours, minutes, isLower) {
19574        if (hours > 11) {
19575            return isLower ? "d'o" : "D'O";
19576        } else {
19577            return isLower ? "d'a" : "D'A";
19578        }
19579    },
19580    calendar: {
19581        sameDay: '[oxhi à] LT',
19582        nextDay: '[demà à] LT',
19583        nextWeek: 'dddd [à] LT',
19584        lastDay: '[ieiri à] LT',
19585        lastWeek: '[sür el] dddd [lasteu à] LT',
19586        sameElse: 'L',
19587    },
19588    relativeTime: {
19589        future: 'osprei %s',
19590        past: 'ja%s',
19591        s: processRelativeTime,
19592        ss: processRelativeTime,
19593        m: processRelativeTime,
19594        mm: processRelativeTime,
19595        h: processRelativeTime,
19596        hh: processRelativeTime,
19597        d: processRelativeTime,
19598        dd: processRelativeTime,
19599        M: processRelativeTime,
19600        MM: processRelativeTime,
19601        y: processRelativeTime,
19602        yy: processRelativeTime,
19603    },
19604    dayOfMonthOrdinalParse: /\d{1,2}\./,
19605    ordinal: '%d.',
19606    week: {
19607        dow: 1, // Monday is the first day of the week.
19608        doy: 4, // The week that contains Jan 4th is the first week of the year.
19609    },
19610}));
19611
19612function processRelativeTime(number, withoutSuffix, key, isFuture) {
19613    var format = {
19614        s: ['viensas secunds', "'iensas secunds"],
19615        ss: [number + ' secunds', '' + number + ' secunds'],
19616        m: ["'n míut", "'iens míut"],
19617        mm: [number + ' míuts', '' + number + ' míuts'],
19618        h: ["'n þora", "'iensa þora"],
19619        hh: [number + ' þoras', '' + number + ' þoras'],
19620        d: ["'n ziua", "'iensa ziua"],
19621        dd: [number + ' ziuas', '' + number + ' ziuas'],
19622        M: ["'n mes", "'iens mes"],
19623        MM: [number + ' mesen', '' + number + ' mesen'],
19624        y: ["'n ar", "'iens ar"],
19625        yy: [number + ' ars', '' + number + ' ars'],
19626    };
19627    return isFuture
19628        ? format[key][0]
19629        : withoutSuffix
19630        ? format[key][0]
19631        : format[key][1];
19632}
19633
19634
19635/***/ }),
19636/* 131 */
19637/***/ (function(module, __webpack_exports__, __webpack_require__) {
19638
19639"use strict";
19640Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
19641/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
19642//! moment.js locale configuration
19643//! locale : Central Atlas Tamazight [tzm]
19644//! author : Abdel Said : https://github.com/abdelsaid
19645
19646
19647
19648/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('tzm', {
19649    months: 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split(
19650        '_'
19651    ),
19652    monthsShort: 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split(
19653        '_'
19654    ),
19655    weekdays: 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
19656    weekdaysShort: 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
19657    weekdaysMin: 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
19658    longDateFormat: {
19659        LT: 'HH:mm',
19660        LTS: 'HH:mm:ss',
19661        L: 'DD/MM/YYYY',
19662        LL: 'D MMMM YYYY',
19663        LLL: 'D MMMM YYYY HH:mm',
19664        LLLL: 'dddd D MMMM YYYY HH:mm',
19665    },
19666    calendar: {
19667        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',
19668        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',
19669        nextWeek: 'dddd [â´´] LT',
19670        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',
19671        lastWeek: 'dddd [â´´] LT',
19672        sameElse: 'L',
19673    },
19674    relativeTime: {
19675        future: 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',
19676        past: 'ⵢⴰⵏ %s',
19677        s: 'ⵉⵎⵉⴽ',
19678        ss: '%d ⵉⵎⵉⴽ',
19679        m: 'ⵎⵉⵏⵓⴺ',
19680        mm: '%d ⵎⵉⵏⵓⴺ',
19681        h: 'ⵙⴰⵄⴰ',
19682        hh: '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',
19683        d: 'ⴰⵙⵙ',
19684        dd: '%d oⵙⵙⴰⵏ',
19685        M: 'ⴰⵢoⵓⵔ',
19686        MM: '%d ⵉⵢⵢⵉⵔⵏ',
19687        y: 'ⴰⵙⴳⴰⵙ',
19688        yy: '%d ⵉⵙⴳⴰⵙⵏ',
19689    },
19690    week: {
19691        dow: 6, // Saturday is the first day of the week.
19692        doy: 12, // The week that contains Jan 12th is the first week of the year.
19693    },
19694}));
19695
19696
19697/***/ }),
19698/* 132 */
19699/***/ (function(module, __webpack_exports__, __webpack_require__) {
19700
19701"use strict";
19702Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
19703/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
19704//! moment.js locale configuration
19705//! locale : Central Atlas Tamazight Latin [tzm-latn]
19706//! author : Abdel Said : https://github.com/abdelsaid
19707
19708
19709
19710/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('tzm-latn', {
19711    months: 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split(
19712        '_'
19713    ),
vendor: 6,983 bytes, lines 19714-19913
19714    monthsShort: 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split(
19715        '_'
19716    ),
19717    weekdays: 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
19718    weekdaysShort: 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
19719    weekdaysMin: 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
19720    longDateFormat: {
19721        LT: 'HH:mm',
19722        LTS: 'HH:mm:ss',
19723        L: 'DD/MM/YYYY',
19724        LL: 'D MMMM YYYY',
19725        LLL: 'D MMMM YYYY HH:mm',
19726        LLLL: 'dddd D MMMM YYYY HH:mm',
19727    },
19728    calendar: {
19729        sameDay: '[asdkh g] LT',
19730        nextDay: '[aska g] LT',
19731        nextWeek: 'dddd [g] LT',
19732        lastDay: '[assant g] LT',
19733        lastWeek: 'dddd [g] LT',
19734        sameElse: 'L',
19735    },
19736    relativeTime: {
19737        future: 'dadkh s yan %s',
19738        past: 'yan %s',
19739        s: 'imik',
19740        ss: '%d imik',
19741        m: 'minuḍ',
19742        mm: '%d minuḍ',
19743        h: 'saɛa',
19744        hh: '%d tassaɛin',
19745        d: 'ass',
19746        dd: '%d ossan',
19747        M: 'ayowr',
19748        MM: '%d iyyirn',
19749        y: 'asgas',
19750        yy: '%d isgasn',
19751    },
19752    week: {
19753        dow: 6, // Saturday is the first day of the week.
19754        doy: 12, // The week that contains Jan 12th is the first week of the year.
19755    },
19756}));
19757
19758
19759/***/ }),
19760/* 133 */
19761/***/ (function(module, __webpack_exports__, __webpack_require__) {
19762
19763"use strict";
19764Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
19765/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
19766//! moment.js locale configuration
19767//! locale : Uyghur (China) [ug-cn]
19768//! author: boyaq : https://github.com/boyaq
19769
19770
19771
19772/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ug-cn', {
19773    months: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split(
19774        '_'
19775    ),
19776    monthsShort: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split(
19777        '_'
19778    ),
19779    weekdays: 'يەكشەنبە_دۈشەنبە_سەيشەنبە_چارشەنبە_پەيشەنبە_جۈمە_شەنبە'.split(
19780        '_'
19781    ),
19782    weekdaysShort: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'),
19783    weekdaysMin: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'),
19784    longDateFormat: {
19785        LT: 'HH:mm',
19786        LTS: 'HH:mm:ss',
19787        L: 'YYYY-MM-DD',
19788        LL: 'YYYY-يىلىM-ئاينىڭD-كۈنى',
19789        LLL: 'YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm',
19790        LLLL: 'dddd، YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm',
19791    },
19792    meridiemParse: /يېرىم كېچە|سەھەر|چۈشتىن بۇرۇن|چۈش|چۈشتىن كېيىن|كەچ/,
19793    meridiemHour: function (hour, meridiem) {
19794        if (hour === 12) {
19795            hour = 0;
19796        }
19797        if (
19798            meridiem === 'يېرىم كېچە' ||
19799            meridiem === 'سەھەر' ||
19800            meridiem === 'چۈشتىن بۇرۇن'
19801        ) {
19802            return hour;
19803        } else if (meridiem === 'چۈشتىن كېيىن' || meridiem === 'كەچ') {
19804            return hour + 12;
19805        } else {
19806            return hour >= 11 ? hour : hour + 12;
19807        }
19808    },
19809    meridiem: function (hour, minute, isLower) {
19810        var hm = hour * 100 + minute;
19811        if (hm < 600) {
19812            return 'يېرىم كېچە';
19813        } else if (hm < 900) {
19814            return 'سەھەر';
19815        } else if (hm < 1130) {
19816            return 'چۈشتىن بۇرۇن';
19817        } else if (hm < 1230) {
19818            return 'چۈش';
19819        } else if (hm < 1800) {
19820            return 'چۈشتىن كېيىن';
19821        } else {
19822            return 'كەچ';
19823        }
19824    },
19825    calendar: {
19826        sameDay: '[بۈگۈن سائەت] LT',
19827        nextDay: '[ئەتە سائەت] LT',
19828        nextWeek: '[كېلەركى] dddd [سائەت] LT',
19829        lastDay: '[تۆنۈگۈن] LT',
19830        lastWeek: '[ئالدىنقى] dddd [سائەت] LT',
19831        sameElse: 'L',
19832    },
19833    relativeTime: {
19834        future: '%s كېيىن',
19835        past: '%s بۇرۇن',
19836        s: 'نەچچە سېكونت',
19837        ss: '%d سېكونت',
19838        m: 'بىر مىنۇت',
19839        mm: '%d مىنۇت',
19840        h: 'بىر سائەت',
19841        hh: '%d سائەت',
19842        d: 'بىر كۈن',
19843        dd: '%d كۈن',
19844        M: 'بىر ئاي',
19845        MM: '%d ئاي',
19846        y: 'بىر يىل',
19847        yy: '%d يىل',
19848    },
19849
19850    dayOfMonthOrdinalParse: /\d{1,2}(-كۈنى|-ئاي|-ھەپتە)/,
19851    ordinal: function (number, period) {
19852        switch (period) {
19853            case 'd':
19854            case 'D':
19855            case 'DDD':
19856                return number + '-كۈنى';
19857            case 'w':
19858            case 'W':
19859                return number + '-ھەپتە';
19860            default:
19861                return number;
19862        }
19863    },
19864    preparse: function (string) {
19865        return string.replace(/،/g, ',');
19866    },
19867    postformat: function (string) {
19868        return string.replace(/,/g, '،');
19869    },
19870    week: {
19871        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
19872        dow: 1, // Monday is the first day of the week.
19873        doy: 7, // The week that contains Jan 1st is the first week of the year.
19874    },
19875}));
19876
19877
19878/***/ }),
19879/* 134 */
19880/***/ (function(module, __webpack_exports__, __webpack_require__) {
19881
19882"use strict";
19883Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
19884/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
19885//! moment.js locale configuration
19886//! locale : Ukrainian [uk]
19887//! author : zemlanin : https://github.com/zemlanin
19888//! Author : Menelion Elensúle : https://github.com/Oire
19889
19890
19891
19892function plural(word, num) {
19893    var forms = word.split('_');
19894    return num % 10 === 1 && num % 100 !== 11
19895        ? forms[0]
19896        : num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20)
19897        ? forms[1]
19898        : forms[2];
19899}
19900function relativeTimeWithPlural(number, withoutSuffix, key) {
19901    var format = {
19902        ss: withoutSuffix ? 'секунда_секунди_секунд' : 'секунду_секунди_секунд',
19903        mm: withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',
19904        hh: withoutSuffix ? 'година_години_годин' : 'годину_години_годин',
19905        dd: 'день_дні_днів',
19906        MM: 'місяць_місяці_місяців',
19907        yy: 'рік_роки_років',
19908    };
19909    if (key === 'm') {
19910        return withoutSuffix ? 'хвилина' : 'хвилину';
19911    } else if (key === 'h') {
19912        return withoutSuffix ? 'година' : 'годину';
19913    } else {
vendor: 9,795 bytes, lines 19914-20208
19914        return number + ' ' + plural(format[key], +number);
19915    }
19916}
19917function weekdaysCaseReplace(m, format) {
19918    var weekdays = {
19919            nominative: 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split(
19920                '_'
19921            ),
19922            accusative: 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split(
19923                '_'
19924            ),
19925            genitive: 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split(
19926                '_'
19927            ),
19928        },
19929        nounCase;
19930
19931    if (m === true) {
19932        return weekdays['nominative']
19933            .slice(1, 7)
19934            .concat(weekdays['nominative'].slice(0, 1));
19935    }
19936    if (!m) {
19937        return weekdays['nominative'];
19938    }
19939
19940    nounCase = /(\[[ВвУу]\]) ?dddd/.test(format)
19941        ? 'accusative'
19942        : /\[?(?:минулої|наступної)? ?\] ?dddd/.test(format)
19943        ? 'genitive'
19944        : 'nominative';
19945    return weekdays[nounCase][m.day()];
19946}
19947function processHoursFunction(str) {
19948    return function () {
19949        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';
19950    };
19951}
19952
19953/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('uk', {
19954    months: {
19955        format: 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split(
19956            '_'
19957        ),
19958        standalone: 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split(
19959            '_'
19960        ),
19961    },
19962    monthsShort: 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split(
19963        '_'
19964    ),
19965    weekdays: weekdaysCaseReplace,
19966    weekdaysShort: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
19967    weekdaysMin: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
19968    longDateFormat: {
19969        LT: 'HH:mm',
19970        LTS: 'HH:mm:ss',
19971        L: 'DD.MM.YYYY',
19972        LL: 'D MMMM YYYY р.',
19973        LLL: 'D MMMM YYYY р., HH:mm',
19974        LLLL: 'dddd, D MMMM YYYY р., HH:mm',
19975    },
19976    calendar: {
19977        sameDay: processHoursFunction('[Сьогодні '),
19978        nextDay: processHoursFunction('[Завтра '),
19979        lastDay: processHoursFunction('[Вчора '),
19980        nextWeek: processHoursFunction('[У] dddd ['),
19981        lastWeek: function () {
19982            switch (this.day()) {
19983                case 0:
19984                case 3:
19985                case 5:
19986                case 6:
19987                    return processHoursFunction('[Минулої] dddd [').call(this);
19988                case 1:
19989                case 2:
19990                case 4:
19991                    return processHoursFunction('[Минулого] dddd [').call(this);
19992            }
19993        },
19994        sameElse: 'L',
19995    },
19996    relativeTime: {
19997        future: 'за %s',
19998        past: '%s тому',
19999        s: 'декілька секунд',
20000        ss: relativeTimeWithPlural,
20001        m: relativeTimeWithPlural,
20002        mm: relativeTimeWithPlural,
20003        h: 'годину',
20004        hh: relativeTimeWithPlural,
20005        d: 'день',
20006        dd: relativeTimeWithPlural,
20007        M: 'місяць',
20008        MM: relativeTimeWithPlural,
20009        y: 'рік',
20010        yy: relativeTimeWithPlural,
20011    },
20012    // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason
20013    meridiemParse: /ночі|ранку|дня|вечора/,
20014    isPM: function (input) {
20015        return /^(дня|вечора)$/.test(input);
20016    },
20017    meridiem: function (hour, minute, isLower) {
20018        if (hour < 4) {
20019            return 'ночі';
20020        } else if (hour < 12) {
20021            return 'ранку';
20022        } else if (hour < 17) {
20023            return 'дня';
20024        } else {
20025            return 'вечора';
20026        }
20027    },
20028    dayOfMonthOrdinalParse: /\d{1,2}-(й|го)/,
20029    ordinal: function (number, period) {
20030        switch (period) {
20031            case 'M':
20032            case 'd':
20033            case 'DDD':
20034            case 'w':
20035            case 'W':
20036                return number + '-й';
20037            case 'D':
20038                return number + '-го';
20039            default:
20040                return number;
20041        }
20042    },
20043    week: {
20044        dow: 1, // Monday is the first day of the week.
20045        doy: 7, // The week that contains Jan 7th is the first week of the year.
20046    },
20047}));
20048
20049
20050/***/ }),
20051/* 135 */
20052/***/ (function(module, __webpack_exports__, __webpack_require__) {
20053
20054"use strict";
20055Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
20056/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
20057//! moment.js locale configuration
20058//! locale : Urdu [ur]
20059//! author : Sawood Alam : https://github.com/ibnesayeed
20060//! author : Zack : https://github.com/ZackVision
20061
20062
20063
20064var months = [
20065        'جنوری',
20066        'فروری',
20067        'مارچ',
20068        'اپریل',
20069        'مئی',
20070        'جون',
20071        'جولائی',
20072        'اگست',
20073        'ستمبر',
20074        'اکتوبر',
20075        'نومبر',
20076        'دسمبر',
20077    ],
20078    days = ['اتوار', 'پیر', 'منگل', 'بدھ', 'جمعرات', 'جمعہ', 'ہفتہ'];
20079
20080/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('ur', {
20081    months: months,
20082    monthsShort: months,
20083    weekdays: days,
20084    weekdaysShort: days,
20085    weekdaysMin: days,
20086    longDateFormat: {
20087        LT: 'HH:mm',
20088        LTS: 'HH:mm:ss',
20089        L: 'DD/MM/YYYY',
20090        LL: 'D MMMM YYYY',
20091        LLL: 'D MMMM YYYY HH:mm',
20092        LLLL: 'dddd، D MMMM YYYY HH:mm',
20093    },
20094    meridiemParse: /صبح|شام/,
20095    isPM: function (input) {
20096        return 'شام' === input;
20097    },
20098    meridiem: function (hour, minute, isLower) {
20099        if (hour < 12) {
20100            return 'صبح';
20101        }
20102        return 'شام';
20103    },
20104    calendar: {
20105        sameDay: '[آج بوقت] LT',
20106        nextDay: '[کل بوقت] LT',
20107        nextWeek: 'dddd [بوقت] LT',
20108        lastDay: '[گذشتہ روز بوقت] LT',
20109        lastWeek: '[گذشتہ] dddd [بوقت] LT',
20110        sameElse: 'L',
20111    },
20112    relativeTime: {
20113        future: '%s بعد',
20114        past: '%s قبل',
20115        s: 'چند سیکنڈ',
20116        ss: '%d سیکنڈ',
20117        m: 'ایک منٹ',
20118        mm: '%d منٹ',
20119        h: 'ایک گھنٹہ',
20120        hh: '%d گھنٹے',
20121        d: 'ایک دن',
20122        dd: '%d دن',
20123        M: 'ایک ماہ',
20124        MM: '%d ماہ',
20125        y: 'ایک سال',
20126        yy: '%d سال',
20127    },
20128    preparse: function (string) {
20129        return string.replace(/،/g, ',');
20130    },
20131    postformat: function (string) {
20132        return string.replace(/,/g, '،');
20133    },
20134    week: {
20135        dow: 1, // Monday is the first day of the week.
20136        doy: 4, // The week that contains Jan 4th is the first week of the year.
20137    },
20138}));
20139
20140
20141/***/ }),
20142/* 136 */
20143/***/ (function(module, __webpack_exports__, __webpack_require__) {
20144
20145"use strict";
20146Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
20147/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
20148//! moment.js locale configuration
20149//! locale : Uzbek [uz]
20150//! author : Sardor Muminov : https://github.com/muminoff
20151
20152
20153
20154/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('uz', {
20155    months: 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split(
20156        '_'
20157    ),
20158    monthsShort: 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),
20159    weekdays: 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),
20160    weekdaysShort: 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),
20161    weekdaysMin: 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),
20162    longDateFormat: {
20163        LT: 'HH:mm',
20164        LTS: 'HH:mm:ss',
20165        L: 'DD/MM/YYYY',
20166        LL: 'D MMMM YYYY',
20167        LLL: 'D MMMM YYYY HH:mm',
20168        LLLL: 'D MMMM YYYY, dddd HH:mm',
20169    },
20170    calendar: {
20171        sameDay: '[Бугун соат] LT [да]',
20172        nextDay: '[Эртага] LT [да]',
20173        nextWeek: 'dddd [куни соат] LT [да]',
20174        lastDay: '[Кеча соат] LT [да]',
20175        lastWeek: '[Утган] dddd [куни соат] LT [да]',
20176        sameElse: 'L',
20177    },
20178    relativeTime: {
20179        future: 'Якин %s ичида',
20180        past: 'Бир неча %s олдин',
20181        s: 'фурсат',
20182        ss: '%d фурсат',
20183        m: 'бир дакика',
20184        mm: '%d дакика',
20185        h: 'бир соат',
20186        hh: '%d соат',
20187        d: 'бир кун',
20188        dd: '%d кун',
20189        M: 'бир ой',
20190        MM: '%d ой',
20191        y: 'бир йил',
20192        yy: '%d йил',
20193    },
20194    week: {
20195        dow: 1, // Monday is the first day of the week.
20196        doy: 7, // The week that contains Jan 4th is the first week of the year.
20197    },
20198}));
20199
20200
20201/***/ }),
20202/* 137 */
20203/***/ (function(module, __webpack_exports__, __webpack_require__) {
20204
20205"use strict";
20206Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
20207/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
20208//! moment.js locale configuration
20209//! locale : Uzbek Latin [uz-latn]
20210//! author : Rasulbek Mirzayev : github.com/Rasulbeeek
20211
20212
20213
20214/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('uz-latn', {
20215    months: 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split(
20216        '_'
20217    ),
20218    monthsShort: 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'),
20219    weekdays: 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split(
20220        '_'
20221    ),
20222    weekdaysShort: 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'),
20223    weekdaysMin: 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'),
20224    longDateFormat: {
20225        LT: 'HH:mm',
20226        LTS: 'HH:mm:ss',
20227        L: 'DD/MM/YYYY',
20228        LL: 'D MMMM YYYY',
20229        LLL: 'D MMMM YYYY HH:mm',
20230        LLLL: 'D MMMM YYYY, dddd HH:mm',
20231    },
20232    calendar: {
20233        sameDay: '[Bugun soat] LT [da]',
20234        nextDay: '[Ertaga] LT [da]',
20235        nextWeek: 'dddd [kuni soat] LT [da]',
20236        lastDay: '[Kecha soat] LT [da]',
20237        lastWeek: "[O'tgan] dddd [kuni soat] LT [da]",
20238        sameElse: 'L',
20239    },
20240    relativeTime: {
20241        future: 'Yaqin %s ichida',
20242        past: 'Bir necha %s oldin',
20243        s: 'soniya',
20244        ss: '%d soniya',
20245        m: 'bir daqiqa',
20246        mm: '%d daqiqa',
20247        h: 'bir soat',
20248        hh: '%d soat',
20249        d: 'bir kun',
20250        dd: '%d kun',
20251        M: 'bir oy',
20252        MM: '%d oy',
20253        y: 'bir yil',
20254        yy: '%d yil',
20255    },
20256    week: {
20257        dow: 1, // Monday is the first day of the week.
20258        doy: 7, // The week that contains Jan 7th is the first week of the year.
20259    },
20260}));
20261
20262
20263/***/ }),
20264/* 138 */
20265/***/ (function(module, __webpack_exports__, __webpack_require__) {
20266
20267"use strict";
20268Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
20269/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
20270//! moment.js locale configuration
20271//! locale : Vietnamese [vi]
20272//! author : Bang Nguyen : https://github.com/bangnk
20273//! author : Chien Kira : https://github.com/chienkira
20274
20275
20276
20277/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('vi', {
20278    months: 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split(
20279        '_'
20280    ),
20281    monthsShort: 'Thg 01_Thg 02_Thg 03_Thg 04_Thg 05_Thg 06_Thg 07_Thg 08_Thg 09_Thg 10_Thg 11_Thg 12'.split(
20282        '_'
20283    ),
20284    monthsParseExact: true,
20285    weekdays: 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split(
20286        '_'
20287    ),
20288    weekdaysShort: 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
20289    weekdaysMin: 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
20290    weekdaysParseExact: true,
20291    meridiemParse: /sa|ch/i,
20292    isPM: function (input) {
20293        return /^ch$/i.test(input);
20294    },
20295    meridiem: function (hours, minutes, isLower) {
20296        if (hours < 12) {
20297            return isLower ? 'sa' : 'SA';
20298        } else {
20299            return isLower ? 'ch' : 'CH';
20300        }
20301    },
20302    longDateFormat: {
20303        LT: 'HH:mm',
20304        LTS: 'HH:mm:ss',
20305        L: 'DD/MM/YYYY',
20306        LL: 'D MMMM [năm] YYYY',
20307        LLL: 'D MMMM [năm] YYYY HH:mm',
20308        LLLL: 'dddd, D MMMM [năm] YYYY HH:mm',
20309        l: 'DD/M/YYYY',
20310        ll: 'D MMM YYYY',
20311        lll: 'D MMM YYYY HH:mm',
20312        llll: 'ddd, D MMM YYYY HH:mm',
20313    },
20314    calendar: {
20315        sameDay: '[Hôm nay lúc] LT',
20316        nextDay: '[Ngày mai lúc] LT',
20317        nextWeek: 'dddd [tuần tới lúc] LT',
20318        lastDay: '[Hôm qua lúc] LT',
20319        lastWeek: 'dddd [tuần trước lúc] LT',
20320        sameElse: 'L',
20321    },
20322    relativeTime: {
20323        future: '%s tới',
20324        past: '%s trước',
20325        s: 'vài giây',
20326        ss: '%d giây',
20327        m: 'một phút',
20328        mm: '%d phút',
20329        h: 'một giờ',
20330        hh: '%d giờ',
20331        d: 'một ngày',
20332        dd: '%d ngày',
20333        w: 'một tuần',
20334        ww: '%d tuần',
20335        M: 'một tháng',
20336        MM: '%d tháng',
20337        y: 'một năm',
20338        yy: '%d năm',
20339    },
20340    dayOfMonthOrdinalParse: /\d{1,2}/,
20341    ordinal: function (number) {
20342        return number;
20343    },
20344    week: {
20345        dow: 1, // Monday is the first day of the week.
20346        doy: 4, // The week that contains Jan 4th is the first week of the year.
20347    },
20348}));
20349
20350
20351/***/ }),
20352/* 139 */
20353/***/ (function(module, __webpack_exports__, __webpack_require__) {
20354
20355"use strict";
20356Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
20357/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
20358//! moment.js locale configuration
20359//! locale : Pseudo [x-pseudo]
20360//! author : Andrew Hood : https://github.com/andrewhood125
20361
20362
20363
20364/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('x-pseudo', {
20365    months: 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split(
20366        '_'
20367    ),
20368    monthsShort: 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.
vendor: 16,384 bytes, lines 20368-20877
20368split(
20369        '_'
20370    ),
20371    monthsParseExact: true,
20372    weekdays: 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split(
20373        '_'
20374    ),
20375    weekdaysShort: 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'),
20376    weekdaysMin: 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'),
20377    weekdaysParseExact: true,
20378    longDateFormat: {
20379        LT: 'HH:mm',
20380        L: 'DD/MM/YYYY',
20381        LL: 'D MMMM YYYY',
20382        LLL: 'D MMMM YYYY HH:mm',
20383        LLLL: 'dddd, D MMMM YYYY HH:mm',
20384    },
20385    calendar: {
20386        sameDay: '[T~ódá~ý át] LT',
20387        nextDay: '[T~ómó~rró~w át] LT',
20388        nextWeek: 'dddd [át] LT',
20389        lastDay: '[Ý~ést~érdá~ý át] LT',
20390        lastWeek: '[L~ást] dddd [át] LT',
20391        sameElse: 'L',
20392    },
20393    relativeTime: {
20394        future: 'í~ñ %s',
20395        past: '%s á~gó',
20396        s: 'á ~féw ~sécó~ñds',
20397        ss: '%d s~écóñ~ds',
20398        m: 'á ~míñ~úté',
20399        mm: '%d m~íñú~tés',
20400        h: 'á~ñ hó~úr',
20401        hh: '%d h~óúrs',
20402        d: 'á ~dáý',
20403        dd: '%d d~áýs',
20404        M: 'á ~móñ~th',
20405        MM: '%d m~óñt~hs',
20406        y: 'á ~ýéár',
20407        yy: '%d ý~éárs',
20408    },
20409    dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
20410    ordinal: function (number) {
20411        var b = number % 10,
20412            output =
20413                ~~((number % 100) / 10) === 1
20414                    ? 'th'
20415                    : b === 1
20416                    ? 'st'
20417                    : b === 2
20418                    ? 'nd'
20419                    : b === 3
20420                    ? 'rd'
20421                    : 'th';
20422        return number + output;
20423    },
20424    week: {
20425        dow: 1, // Monday is the first day of the week.
20426        doy: 4, // The week that contains Jan 4th is the first week of the year.
20427    },
20428}));
20429
20430
20431/***/ }),
20432/* 140 */
20433/***/ (function(module, __webpack_exports__, __webpack_require__) {
20434
20435"use strict";
20436Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
20437/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
20438//! moment.js locale configuration
20439//! locale : Yoruba Nigeria [yo]
20440//! author : Atolagbe Abisoye : https://github.com/andela-batolagbe
20441
20442
20443
20444/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('yo', {
20445    months: 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split(
20446        '_'
20447    ),
20448    monthsShort: 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'),
20449    weekdays: 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'),
20450    weekdaysShort: 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'),
20451    weekdaysMin: 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'),
20452    longDateFormat: {
20453        LT: 'h:mm A',
20454        LTS: 'h:mm:ss A',
20455        L: 'DD/MM/YYYY',
20456        LL: 'D MMMM YYYY',
20457        LLL: 'D MMMM YYYY h:mm A',
20458        LLLL: 'dddd, D MMMM YYYY h:mm A',
20459    },
20460    calendar: {
20461        sameDay: '[Ònì ni] LT',
20462        nextDay: '[Ọ̀la ni] LT',
20463        nextWeek: "dddd [Ọsẹ̀ tón'bọ] [ni] LT",
20464        lastDay: '[Àna ni] LT',
20465        lastWeek: 'dddd [Ọsẹ̀ tólọ́] [ni] LT',
20466        sameElse: 'L',
20467    },
20468    relativeTime: {
20469        future: 'ní %s',
20470        past: '%s kọjá',
20471        s: 'ìsẹjú aayá die',
20472        ss: 'aayá %d',
20473        m: 'ìsẹjú kan',
20474        mm: 'ìsẹjú %d',
20475        h: 'wákati kan',
20476        hh: 'wákati %d',
20477        d: 'ọjọ́ kan',
20478        dd: 'ọjọ́ %d',
20479        M: 'osù kan',
20480        MM: 'osù %d',
20481        y: 'ọdún kan',
20482        yy: 'ọdún %d',
20483    },
20484    dayOfMonthOrdinalParse: /ọjọ́\s\d{1,2}/,
20485    ordinal: 'ọjọ́ %d',
20486    week: {
20487        dow: 1, // Monday is the first day of the week.
20488        doy: 4, // The week that contains Jan 4th is the first week of the year.
20489    },
20490}));
20491
20492
20493/***/ }),
20494/* 141 */
20495/***/ (function(module, __webpack_exports__, __webpack_require__) {
20496
20497"use strict";
20498Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
20499/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
20500//! moment.js locale configuration
20501//! locale : Chinese (China) [zh-cn]
20502//! author : suupic : https://github.com/suupic
20503//! author : Zeno Zeng : https://github.com/zenozeng
20504//! author : uu109 : https://github.com/uu109
20505
20506
20507
20508/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('zh-cn', {
20509    months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(
20510        '_'
20511    ),
20512    monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(
20513        '_'
20514    ),
20515    weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
20516    weekdaysShort: '周日_周一_周二_周三_周四_周五_周六'.split('_'),
20517    weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
20518    longDateFormat: {
20519        LT: 'HH:mm',
20520        LTS: 'HH:mm:ss',
20521        L: 'YYYY/MM/DD',
20522        LL: 'YYYY年M月D日',
20523        LLL: 'YYYY年M月D日Ah点mm分',
20524        LLLL: 'YYYY年M月D日ddddAh点mm分',
20525        l: 'YYYY/M/D',
20526        ll: 'YYYY年M月D日',
20527        lll: 'YYYY年M月D日 HH:mm',
20528        llll: 'YYYY年M月D日dddd HH:mm',
20529    },
20530    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
20531    meridiemHour: function (hour, meridiem) {
20532        if (hour === 12) {
20533            hour = 0;
20534        }
20535        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
20536            return hour;
20537        } else if (meridiem === '下午' || meridiem === '晚上') {
20538            return hour + 12;
20539        } else {
20540            // '中午'
20541            return hour >= 11 ? hour : hour + 12;
20542        }
20543    },
20544    meridiem: function (hour, minute, isLower) {
20545        var hm = hour * 100 + minute;
20546        if (hm < 600) {
20547            return '凌晨';
20548        } else if (hm < 900) {
20549            return '早上';
20550        } else if (hm < 1130) {
20551            return '上午';
20552        } else if (hm < 1230) {
20553            return '中午';
20554        } else if (hm < 1800) {
20555            return '下午';
20556        } else {
20557            return '晚上';
20558        }
20559    },
20560    calendar: {
20561        sameDay: '[今天]LT',
20562        nextDay: '[明天]LT',
20563        nextWeek: function (now) {
20564            if (now.week() !== this.week()) {
20565                return '[下]dddLT';
20566            } else {
20567                return '[本]dddLT';
20568            }
20569        },
20570        lastDay: '[昨天]LT',
20571        lastWeek: function (now) {
20572            if (this.week() !== now.week()) {
20573                return '[上]dddLT';
20574            } else {
20575                return '[本]dddLT';
20576            }
20577        },
20578        sameElse: 'L',
20579    },
20580    dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/,
20581    ordinal: function (number, period) {
20582        switch (period) {
20583            case 'd':
20584            case 'D':
20585            case 'DDD':
20586                return number + '日';
20587            case 'M':
20588                return number + '月';
20589            case 'w':
20590            case 'W':
20591                return number + '周';
20592            default:
20593                return number;
20594        }
20595    },
20596    relativeTime: {
20597        future: '%s后',
20598        past: '%s前',
20599        s: '几秒',
20600        ss: '%d 秒',
20601        m: '1 分钟',
20602        mm: '%d 分钟',
20603        h: '1 小时',
20604        hh: '%d 小时',
20605        d: '1 天',
20606        dd: '%d 天',
20607        w: '1 周',
20608        ww: '%d 周',
20609        M: '1 个月',
20610        MM: '%d 个月',
20611        y: '1 å¹´',
20612        yy: '%d å¹´',
20613    },
20614    week: {
20615        // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
20616        dow: 1, // Monday is the first day of the week.
20617        doy: 4, // The week that contains Jan 4th is the first week of the year.
20618    },
20619}));
20620
20621
20622/***/ }),
20623/* 142 */
20624/***/ (function(module, __webpack_exports__, __webpack_require__) {
20625
20626"use strict";
20627Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
20628/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
20629//! moment.js locale configuration
20630//! locale : Chinese (Hong Kong) [zh-hk]
20631//! author : Ben : https://github.com/ben-lin
20632//! author : Chris Lam : https://github.com/hehachris
20633//! author : Konstantin : https://github.com/skfd
20634//! author : Anthony : https://github.com/anthonylau
20635
20636
20637
20638/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('zh-hk', {
20639    months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(
20640        '_'
20641    ),
20642    monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(
20643        '_'
20644    ),
20645    weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
20646    weekdaysShort: '週日_週一_週二_週三_週四_週五_週六'.split('_'),
20647    weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
20648    longDateFormat: {
20649        LT: 'HH:mm',
20650        LTS: 'HH:mm:ss',
20651        L: 'YYYY/MM/DD',
20652        LL: 'YYYY年M月D日',
20653        LLL: 'YYYY年M月D日 HH:mm',
20654        LLLL: 'YYYY年M月D日dddd HH:mm',
20655        l: 'YYYY/M/D',
20656        ll: 'YYYY年M月D日',
20657        lll: 'YYYY年M月D日 HH:mm',
20658        llll: 'YYYY年M月D日dddd HH:mm',
20659    },
20660    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
20661    meridiemHour: function (hour, meridiem) {
20662        if (hour === 12) {
20663            hour = 0;
20664        }
20665        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
20666            return hour;
20667        } else if (meridiem === '中午') {
20668            return hour >= 11 ? hour : hour + 12;
20669        } else if (meridiem === '下午' || meridiem === '晚上') {
20670            return hour + 12;
20671        }
20672    },
20673    meridiem: function (hour, minute, isLower) {
20674        var hm = hour * 100 + minute;
20675        if (hm < 600) {
20676            return '凌晨';
20677        } else if (hm < 900) {
20678            return '早上';
20679        } else if (hm < 1200) {
20680            return '上午';
20681        } else if (hm === 1200) {
20682            return '中午';
20683        } else if (hm < 1800) {
20684            return '下午';
20685        } else {
20686            return '晚上';
20687        }
20688    },
20689    calendar: {
20690        sameDay: '[今天]LT',
20691        nextDay: '[明天]LT',
20692        nextWeek: '[下]ddddLT',
20693        lastDay: '[昨天]LT',
20694        lastWeek: '[上]ddddLT',
20695        sameElse: 'L',
20696    },
20697    dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/,
20698    ordinal: function (number, period) {
20699        switch (period) {
20700            case 'd':
20701            case 'D':
20702            case 'DDD':
20703                return number + '日';
20704            case 'M':
20705                return number + '月';
20706            case 'w':
20707            case 'W':
20708                return number + '週';
20709            default:
20710                return number;
20711        }
20712    },
20713    relativeTime: {
20714        future: '%s後',
20715        past: '%s前',
20716        s: '幾秒',
20717        ss: '%d 秒',
20718        m: '1 分鐘',
20719        mm: '%d 分鐘',
20720        h: '1 小時',
20721        hh: '%d 小時',
20722        d: '1 天',
20723        dd: '%d 天',
20724        M: '1 個月',
20725        MM: '%d 個月',
20726        y: '1 å¹´',
20727        yy: '%d å¹´',
20728    },
20729}));
20730
20731
20732/***/ }),
20733/* 143 */
20734/***/ (function(module, __webpack_exports__, __webpack_require__) {
20735
20736"use strict";
20737Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
20738/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
20739//! moment.js locale configuration
20740//! locale : Chinese (Macau) [zh-mo]
20741//! author : Ben : https://github.com/ben-lin
20742//! author : Chris Lam : https://github.com/hehachris
20743//! author : Tan Yuanhong : https://github.com/le0tan
20744
20745
20746
20747/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('zh-mo', {
20748    months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(
20749        '_'
20750    ),
20751    monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(
20752        '_'
20753    ),
20754    weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
20755    weekdaysShort: '週日_週一_週二_週三_週四_週五_週六'.split('_'),
20756    weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
20757    longDateFormat: {
20758        LT: 'HH:mm',
20759        LTS: 'HH:mm:ss',
20760        L: 'DD/MM/YYYY',
20761        LL: 'YYYY年M月D日',
20762        LLL: 'YYYY年M月D日 HH:mm',
20763        LLLL: 'YYYY年M月D日dddd HH:mm',
20764        l: 'D/M/YYYY',
20765        ll: 'YYYY年M月D日',
20766        lll: 'YYYY年M月D日 HH:mm',
20767        llll: 'YYYY年M月D日dddd HH:mm',
20768    },
20769    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
20770    meridiemHour: function (hour, meridiem) {
20771        if (hour === 12) {
20772            hour = 0;
20773        }
20774        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
20775            return hour;
20776        } else if (meridiem === '中午') {
20777            return hour >= 11 ? hour : hour + 12;
20778        } else if (meridiem === '下午' || meridiem === '晚上') {
20779            return hour + 12;
20780        }
20781    },
20782    meridiem: function (hour, minute, isLower) {
20783        var hm = hour * 100 + minute;
20784        if (hm < 600) {
20785            return '凌晨';
20786        } else if (hm < 900) {
20787            return '早上';
20788        } else if (hm < 1130) {
20789            return '上午';
20790        } else if (hm < 1230) {
20791            return '中午';
20792        } else if (hm < 1800) {
20793            return '下午';
20794        } else {
20795            return '晚上';
20796        }
20797    },
20798    calendar: {
20799        sameDay: '[今天] LT',
20800        nextDay: '[明天] LT',
20801        nextWeek: '[下]dddd LT',
20802        lastDay: '[昨天] LT',
20803        lastWeek: '[上]dddd LT',
20804        sameElse: 'L',
20805    },
20806    dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/,
20807    ordinal: function (number, period) {
20808        switch (period) {
20809            case 'd':
20810            case 'D':
20811            case 'DDD':
20812                return number + '日';
20813            case 'M':
20814                return number + '月';
20815            case 'w':
20816            case 'W':
20817                return number + '週';
20818            default:
20819                return number;
20820        }
20821    },
20822    relativeTime: {
20823        future: '%s內',
20824        past: '%s前',
20825        s: '幾秒',
20826        ss: '%d 秒',
20827        m: '1 分鐘',
20828        mm: '%d 分鐘',
20829        h: '1 小時',
20830        hh: '%d 小時',
20831        d: '1 天',
20832        dd: '%d 天',
20833        M: '1 個月',
20834        MM: '%d 個月',
20835        y: '1 å¹´',
20836        yy: '%d å¹´',
20837    },
20838}));
20839
20840
20841/***/ }),
20842/* 144 */
20843/***/ (function(module, __webpack_exports__, __webpack_require__) {
20844
20845"use strict";
20846Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
20847/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__moment__ = __webpack_require__(0);
20848//! moment.js locale configuration
20849//! locale : Chinese (Taiwan) [zh-tw]
20850//! author : Ben : https://github.com/ben-lin
20851//! author : Chris Lam : https://github.com/hehachris
20852
20853
20854
20855/* harmony default export */ __webpack_exports__["default"] = (__WEBPACK_IMPORTED_MODULE_0__moment__["a" /* default */].defineLocale('zh-tw', {
20856    months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(
20857        '_'
20858    ),
20859    monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(
20860        '_'
20861    ),
20862    weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
20863    weekdaysShort: '週日_週一_週二_週三_週四_週五_週六'.split('_'),
20864    weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
20865    longDateFormat: {
20866        LT: 'HH:mm',
20867        LTS: 'HH:mm:ss',
20868        L: 'YYYY/MM/DD',
20869        LL: 'YYYY年M月D日',
20870        LLL: 'YYYY年M月D日 HH:mm',
20871        LLLL: 'YYYY年M月D日dddd HH:mm',
20872        l: 'YYYY/M/D',
20873        ll: 'YYYY年M月D日',
20874        lll: 'YYYY年M月D日 HH:mm',
20875        llll: 'YYYY年M月D日dddd HH:mm',
20876    },
20877    meridiemP
20877arse: /凌晨|早上|上午|中午|下午|晚上/,
20878    meridiemHour: function (hour, meridiem) {
20879        if (hour === 12) {
20880            hour = 0;
20881        }
20882        if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
20883            return hour;
20884        } else if (meridiem === '中午') {
20885            return hour >= 11 ? hour : hour + 12;
20886        } else if (meridiem === '下午' || meridiem === '晚上') {
20887            return hour + 12;
20888        }
20889    },
20890    meridiem: function (hour, minute, isLower) {
20891        var hm = hour * 100 + minute;
20892        if (hm < 600) {
20893            return '凌晨';
20894        } else if (hm < 900) {
20895            return '早上';
20896        } else if (hm < 1130) {
20897            return '上午';
20898        } else if (hm < 1230) {
20899            return '中午';
20900        } else if (hm < 1800) {
20901            return '下午';
20902        } else {
20903            return '晚上';
20904        }
20905    },
20906    calendar: {
20907        sameDay: '[今天] LT',
20908        nextDay: '[明天] LT',
20909        nextWeek: '[下]dddd LT',
20910        lastDay: '[昨天] LT',
20911        lastWeek: '[上]dddd LT',
20912        sameElse: 'L',
20913    },
20914    dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/,
20915    ordinal: function (number, period) {
20916        switch (period) {
20917            case 'd':
20918            case 'D':
20919            case 'DDD':
20920                return number + '日';
20921            case 'M':
20922                return number + '月';
20923            case 'w':
20924            case 'W':
20925                return number + '週';
20926            default:
20927                return number;
20928        }
20929    },
20930    relativeTime: {
20931        future: '%s後',
20932        past: '%s前',
20933        s: '幾秒',
20934        ss: '%d 秒',
20935        m: '1 分鐘',
20936        mm: '%d 分鐘',
20937        h: '1 小時',
20938        hh: '%d 小時',
20939        d: '1 天',
20940        dd: '%d 天',
20941        M: '1 個月',
20942        MM: '%d 個月',
20943        y: '1 å¹´',
20944        yy: '%d å¹´',
20945    },
20946}));
20947
20948
20949/***/ }),
20950/* 145 */
20951/***/ (function(module, __webpack_exports__, __webpack_require__) {
20952
20953"use strict";
20954/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
20955/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_dom__ = __webpack_require__(3);
20956/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_utils__ = __webpack_require__(1);
20957/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils_get_support__ = __webpack_require__(146);
20958/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__utils_get_device__ = __webpack_require__(167);
20959/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_get_browser__ = __webpack_require__(168);
20960/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__modules_resize_resize__ = __webpack_require__(169);
20961/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__modules_observer_observer__ = __webpack_require__(170);
20962/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__modular__ = __webpack_require__(171);
20963/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__events_emitter__ = __webpack_require__(172);
20964/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__update_index__ = __webpack_require__(173);
20965/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__translate_index__ = __webpack_require__(183);
20966/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__transition_index__ = __webpack_require__(189);
20967/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__slide_index__ = __webpack_require__(193);
20968/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__loop_index__ = __webpack_require__(201);
20969/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__grab_cursor_index__ = __webpack_require__(205);
20970/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__manipulation_index__ = __webpack_require__(208);
20971/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__events_index__ = __webpack_require__(214);
20972/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__breakpoints_index__ = __webpack_require__(221);
20973/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__classes_index__ = __webpack_require__(224);
20974/* harmony import */ var __WEBPACK_IMPORTED_MODULE_20__images_index__ = __webpack_require__(227);
20975/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21__check_overflow_index__ = __webpack_require__(230);
20976/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22__defaults__ = __webpack_require__(231);
20977function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
20978
20979function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
20980
20981/* eslint no-param-reassign: "off" */
20982
20983
20984
20985
20986
20987
20988
20989
20990
20991
20992
20993
20994
20995
20996
20997
20998
20999
21000
21001
21002
21003
21004
21005var prototypes = {
21006  modular: __WEBPACK_IMPORTED_MODULE_8__modular__["a" /* default */],
21007  eventsEmitter: __WEBPACK_IMPORTED_MODULE_9__events_emitter__["a" /* default */],
21008  update: __WEBPACK_IMPORTED_MODULE_10__update_index__["a" /* default */],
21009  translate: __WEBPACK_IMPORTED_MODULE_11__translate_index__["a" /* default */],
21010  transition: __WEBPACK_IMPORTED_MODULE_12__transition_index__["a" /* default */],
21011  slide: __WEBPACK_IMPORTED_MODULE_13__slide_index__["a" /* default */],
21012  loop: __WEBPACK_IMPORTED_MODULE_14__loop_index__["a" /* default */],
21013  grabCursor: __WEBPACK_IMPORTED_MODULE_15__grab_cursor_index__["a" /* default */],
21014  manipulation: __WEBPACK_IMPORTED_MODULE_16__manipulation_index__["a" /* default */],
21015  events: __WEBPACK_IMPORTED_MODULE_17__events_index__["a" /* default */],
21016  breakpoints: __WEBPACK_IMPORTED_MODULE_18__breakpoints_index__["a" /* default */],
21017  checkOverflow: __WEBPACK_IMPORTED_MODULE_21__check_overflow_index__["a" /* default */],
21018  classes: __WEBPACK_IMPORTED_MODULE_19__classes_index__["a" /* default */],
21019  images: __WEBPACK_IMPORTED_MODULE_20__images_index__["a" /* default */]
21020};
21021var extendedDefaults = {};
21022
21023var Swiper = /*#__PURE__*/function () {
21024  function Swiper() {
21025    var el;
21026    var params;
21027
21028    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
21029      args[_key] = arguments[_key];
21030    }
21031
21032    if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') {
21033      params = args[0];
21034    } else {
21035      el = args[0];
21036      params = args[1];
21037    }
21038
21039    if (!params) params = {};
21040    params = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])({}, params);
21041    if (el && !params.el) params.el = el;
21042
21043    if (params.el && Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(params.el).length > 1) {
21044      var swipers = [];
21045      Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(params.el).each(function (containerEl) {
21046        var newParams = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])({}, params, {
21047          el: containerEl
21048        });
21049        swipers.push(new Swiper(newParams));
21050      });
21051      return swipers;
21052    } // Swiper Instance
21053
21054
21055    var swiper = this;
21056    swiper.__swiper__ = true;
21057    swiper.support = Object(__WEBPACK_IMPORTED_MODULE_3__utils_get_support__["a" /* getSupport */])();
21058    swiper.device = Object(__WEBPACK_IMPORTED_MODULE_4__utils_get_device__["a" /* getDevice */])({
21059      userAgent: params.userAgent
21060    });
21061    swiper.browser = Object(__WEBPACK_IMPORTED_MODULE_5__utils_get_browser__["a" /* getBrowser */])();
21062    swiper.eventsListeners = {};
21063    swiper.eventsAnyListeners = [];
21064
21065    if (typeof swiper.modules === 'undefined') {
21066      swiper.modules = {};
21067    }
21068
21069    Object.keys(swiper.modules).forEach(function (moduleName) {
21070      var module = swiper.modules[moduleName];
21071
21072      if (module.params) {
21073        var moduleParamName = Object.keys(module.params)[0];
21074        var moduleParams = module.params[moduleParamName];
21075        if (typeof moduleParams !== 'object' || moduleParams === null) return;
21076
21077        if (['navigation', 'pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] === true) {
21078          params[moduleParamName] = {
21079            auto: true
21080          };
21081        }
21082
21083        if (!(moduleParamName in params && 'enabled' in moduleParams)) return;
21084
21085        if (params[moduleParamName] === true) {
21086          params[moduleParamName] = {
21087            enabled: true
21088          };
21089        }
21090
21091        if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {
21092          params[moduleParamName].enabled = true;
21093        }
21094
21095        if (!params[moduleParamName]) params[moduleParamName] = {
21096          enabled: false
21097        };
21098      }
21099    }); // Extend defaults with modules params
21100
21101    var swiperParams = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])({}, __WEBPACK_IMPORTED_MODULE_22__defaults__["a" /* default */]);
21102    swiper.useParams(swiperParams); // Extend defaults with passed params
21103
21104    swiper.params = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])({}, swiperParams, extendedDefaults, params);
21105    swiper.originalParams = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])({}, swiper.params);
21106    swiper.passedParams = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])({}, params); // add event listeners
21107
21108    if (swiper.params && swiper.params.on) {
21109      Object.keys(swiper.params.on).forEach(function (eventName) {
21110        swiper.on(eventName, swiper.params.on[eventName]);
21111      });
21112    }
21113
21114    if (swiper.params && swiper.params.onAny) {
21115      swiper.onAny(swiper.params.onAny);
21116    } // Save Dom lib
21117
21118
21119    swiper.$ = __WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */]; // Extend Swiper
21120
21121    Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])(swiper, {
21122      enabled: swiper.params.enabled,
21123      el: el,
21124      // Classes
21125      classNames: [],
21126      // Slides
21127      slides: Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(),
21128      slidesGrid: [],
21129      snapGrid: [],
21130      slidesSizesGrid: [],
21131      // isDirection
21132      isHorizontal: function isHorizontal() {
21133        return swiper.params.direction === 'horizontal';
21134      },
21135      isVertical: function isVertical() {
21136        return swiper.params.direction === 'vertical';
21137      },
21138      // Indexes
21139      activeIndex: 0,
21140      realIndex: 0,
21141      //
21142      isBeginning: true,
21143      isEnd: false,
21144      // Props
21145      translate: 0,
21146      previousTranslate: 0,
21147      progress: 0,
21148      velocity: 0,
21149      animating: false,
21150      // Locks
21151      allowSlideNext: swiper.params.allowSlideNext,
21152      allowSlidePrev: swiper.params.allowSlidePrev,
21153      // Touch Events
21154      touchEvents: function touchEvents() {
21155        var touch = ['touchstart', 'touchmove', 'touchend', 'touchcancel'];
21156        var desktop = ['mousedown', 'mousemove', 'mouseup'];
21157
21158        if (swiper.support.pointerEvents) {
21159          desktop = ['pointerdown', 'pointermove', 'pointerup'];
21160        }
21161
21162        swiper.touchEventsTouch = {
21163          start: touch[0],
21164          move: touch[1],
21165          end: touch[2],
21166          cancel: touch[3]
21167        };
21168        swiper.touchEventsDesktop = {
21169          start: desktop[0],
21170          move: desktop[1],
21171          end: desktop[2]
21172        };
21173        return swiper.support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch : swiper.touchEventsDesktop;
21174      }(),
21175      touchEventsData: {
21176        isTouched: undefined,
21177        isMoved: undefined,
21178        allowTouchCallbacks: undefined,
21179        touchStartTime: undefined,
21180        isScrolling: undefined,
21181        currentTranslate: undefined,
21182        startTranslate: undefined,
21183        allowThresholdMove: undefined,
21184        // Form elements to match
21185        focusableElements: swiper.params.focusableElements,
21186        // Last click time
21187        lastClickTime: Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["i" /* now */])(),
21188        clickTimeout: undefined,
21189        // Velocities
21190        velocities: [],
21191        allowMomentumBounce: undefined,
21192        isTouchEvent: undefined,
21193        startMoving: undefined
21194      },
21195      // Clicks
21196      allowClick: true,
21197      // Touches
21198      allowTouchMove: swiper.params.allowTouchMove,
21199      touches: {
21200        startX: 0,
21201        startY: 0,
21202        currentX: 0,
21203        currentY: 0,
21204        diff: 0
21205      },
21206      // Images
21207      imagesToLoad: [],
21208      imagesLoaded: 0
21209    }); // Install Modules
21210
21211    swiper.useModules();
21212    swiper.emit('_swiper'); // Init
21213
21214    if (swiper.params.init) {
21215      swiper.init();
21216    } // Return app instance
21217
21218
21219    return swiper;
21220  }
21221
21222  var _proto = Swiper.prototype;
21223
21224  _proto.enable = function enable() {
21225    var swiper = this;
21226    if (swiper.enabled) return;
21227    swiper.enabled = true;
21228
21229    if (swiper.params.grabCursor) {
21230      swiper.setGrabCursor();
21231    }
21232
21233    swiper.emit('enable');
21234  };
21235
21236  _proto.disable = function disable() {
21237    var swiper = this;
21238    if (!swiper.enabled) return;
21239    swiper.enabled = false;
21240
21241    if (swiper.params.grabCursor) {
21242      swiper.unsetGrabCursor();
21243    }
21244
21245    swiper.emit('disable');
21246  };
21247
21248  _proto.setProgress = function setProgress(progress, speed) {
21249    var swiper = this;
21250    progress = Math.min(Math.max(progress, 0), 1);
21251    var min = swiper.minTranslate();
21252    var max = swiper.maxTranslate();
21253    var current = (max - min) * progress + min;
21254    swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);
21255    swiper.updateActiveIndex();
21256    swiper.updateSlidesClasses();
21257  };
21258
21259  _proto.emitContainerClasses = function emitContainerClasses() {
21260    var swiper = this;
21261    if (!swiper.params._emitClasses || !swiper.el) return;
21262    var classes = swiper.el.className.split(' ').filter(function (className) {
21263      return className.indexOf('swiper-container') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0;
21264    });
21265    swiper.emit('_containerClasses', classes.join(' '));
21266  };
21267
21268  _proto.getSlideClasses = function getSlideClasses(slideEl) {
21269    var swiper = this;
21270    return slideEl.className.split(' ').filter(function (className) {
21271      return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0;
21272    }).join(' ');
21273  };
21274
21275  _proto.emitSlidesClasses = function emitSlidesClasses() {
21276    var swiper = this;
21277    if (!swiper.params._emitClasses || !swiper.el) return;
21278    var updates = [];
21279    swiper.slides.each(function (slideEl) {
21280      var classNames = swiper.getSlideClasses(slideEl);
21281      updates.push({
21282        slideEl: slideEl,
21283        classNames: classNames
21284      });
21285      swiper.emit('_slideClass', slideEl, classNames);
21286    });
21287    swiper.emit('_slideClasses', updates);
21288  };
21289
21290  _proto.slidesPerViewDynamic = function slidesPerViewDynamic() {
21291    var swiper = this;
21292    var params = swiper.params,
21293        slides = swiper.slides,
21294        slidesGrid = swiper.slidesGrid,
21295        swiperSize = swiper.size,
21296        activeIndex = swiper.activeIndex;
21297    var spv = 1;
21298
21299    if (params.centeredSlides) {
21300      var slideSize = slides[activeIndex].swiperSlideSize;
21301      var breakLoop;
21302
21303      for (var i = activeIndex + 1; i < slides.length; i += 1) {
21304        if (slides[i] && !breakLoop) {
21305          slideSize += slides[i].swiperSlideSize;
21306          spv += 1;
21307          if (slideSize > swiperSize) breakLoop = true;
21308        }
21309      }
21310
21311      for (var _i = activeIndex - 1; _i >= 0; _i -= 1) {
21312        if (slides[_i] && !breakLoop) {
21313          slideSize += slides[_i].swiperSlideSize;
21314          spv += 1;
21315          if (slideSize > swiperSize) breakLoop = true;
21316        }
21317      }
21318    } else {
21319      for (var _i2 = activeIndex + 1; _i2 < slides.length; _i2 += 1) {
21320        if (slidesGrid[_i2] - slidesGrid[activeIndex] < swiperSize) {
21321          spv += 1;
21322        }
21323      }
21324    }
21325
21326    return spv;
21327  };
21328
21329  _proto.update = function update() {
21330    var swiper = this;
21331    if (!swiper || swiper.destroyed) return;
21332    var snapGrid = swiper.snapGrid,
21333        params = swiper.params; // Breakpoints
21334
21335    if (params.breakpoints) {
21336      swiper.setBreakpoint();
21337    }
21338
21339    swiper.updateSize();
21340    swiper.updateSlides();
21341    swiper.updateProgress();
21342    swiper.updateSlidesClasses();
21343
21344    function setTranslate() {
21345      var translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
21346      var newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
21347      swiper.setTranslate(newTranslate);
21348      swiper.updateActiveIndex();
21349      swiper.updateSlidesClasses();
21350    }
21351
21352    var translated;
21353
21354    if (swiper.params.freeMode) {
21355      setTranslate();
21356
21357      if (swiper.params.autoHeight) {
21358        swiper.updateAutoHeight();
21359      }
21360    } else {
21361      if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) {
21362        translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true);
21363      } else {
21364        translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
21365      }
21366
21367      if (!translated) {
21368        setTranslate();
21369      }
21370    }
21371
21372    if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
21373      swiper.checkOverflow();
21374    }
21375
21376    swiper.emit('update');
21377  };
21378
21379  _proto.changeDirection = function changeDirection(newDirection, needUpdate) {
21380    if (needUpdate === void 0) {
21381      needUpdate = true;
21382    }
21383
21384    var swiper = this;
21385    var currentDirection = swiper.params.direction;
21386
21387    if (!newDirection) {
21388      // eslint-disable-next-line
21389      newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
21390    }
21391
21392    if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
21393      return swiper;
21394    }
21395
21396    swiper.$el.removeClass("" + swiper.params.containerModifierClass + currentDirection).addClass("" + swiper.params.containerModifierClass + newDirection);
21397    swiper.emitContainerClasses();
21398    swiper.params.direction = newDirection;
21399    swiper.slides.each(function (slideEl) {
21400      if (newDirection === 'vertical') {
21401        slideEl.style.width = '';
21402      } else {
21403        slideEl.style.height = '';
21404      }
21405    });
21406    swiper.emit('changeDirection');
21407    if (needUpdate) swiper.update();
21408    return swiper;
21409  };
21410
21411  _proto.mount = function mount(el) {
21412    var swiper = this;
21413    if (swiper.mounted) return true; // Find el
21414
21415    var $el = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(el || swiper.params.el);
21416    el = $el[0];
21417
21418    if (!el) {
21419      return false;
21420    }
21421
21422    el.swiper = swiper;
21423
21424    var getWrapperSelector = function getWrapperSelector() {
21425      return "." + (swiper.params.wrapperClass || '').trim().split(' ').join('.');
21426    };
21427
21428    var getWrapper = function getWrapper() {
21429      if (el && el.shadowRoot && el.shadowRoot.querySelector) {
21430        var res = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(el.shadowRoot.querySelector(getWrapperSelector())); // Children needs to return slot items
21431
21432        res.children = function (options) {
21433          return $el.children(options);
21434        };
21435
21436        return res;
21437      }
21438
21439      return $el.children(getWrapperSelector());
21440    }; // Find Wrapper
21441
21442
21443    var $wrapperEl = getWrapper();
21444
21445    if ($wrapperEl.length === 0 && swiper.params.createElements) {
21446      var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
21447      var wrapper = document.createElement('div');
21448      $wrapperEl = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(wrapper);
21449      wrapper.className = swiper.params.wrapperClass;
21450      $el.append(wrapper);
21451      $el.children("." + swiper.params.slideClass).each(function (slideEl) {
21452        $wrapperEl.append(slideEl);
21453      });
21454    }
21455
21456    Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])(swiper, {
21457      $el: $el,
21458      el: el,
21459      $wrapperEl: $wrapperEl,
21460      wrapperEl: $wrapperEl[0],
21461      mounted: true,
21462      // RTL
21463      rtl: el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl',
21464      rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'),
21465      wrongRTL: $wrapperEl.css('display') === '-webkit-box'
21466    });
21467    return true;
21468  };
21469
21470  _proto.init = function init(el) {
21471    var swiper = this;
21472    if (swiper.initialized) return swiper;
21473    var mounted = swiper.mount(el);
21474    if (mounted === false) return swiper;
21475    swiper.emit('beforeInit'); // Set breakpoint
21476
21477    if (swiper.params.breakpoints) {
21478      swiper.setBreakpoint();
21479    } // Add Classes
21480
21481
21482    swiper.addClasses(); // Create loop
21483
21484    if (swiper.params.loop) {
21485      swiper.loopCreate();
21486    } // Update size
21487
21488
21489    swiper.updateSize(); // Update slides
21490
21491    swiper.updateSlides();
21492
21493    if (swiper.params.watchOverflow) {
21494      swiper.checkOverflow();
21495    } // Set Grab Cursor
21496
21497
21498    if (swiper.params.grabCursor && swiper.enabled) {
21499      swiper.setGrabCursor();
21500    }
21501
21502    if (swiper.params.preloadImages) {
21503      swiper.preloadImages();
21504    } // Slide To Initial Slide
21505
21506
21507    if (swiper.params.loop) {
21508      swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params.runCallbacksOnInit, false, true);
21509    } else {
21510      swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
21511    } // Attach events
21512
21513
21514    swiper.attachEvents(); // Init Flag
21515
21516    swiper.initialized = true; // Emit
21517
21518    swiper.emit('init');
21519    swiper.emit('afterInit');
21520    return swiper;
21521  };
21522
21523  _proto.destroy = function destroy(deleteInstance, cleanStyles) {
21524    if (deleteInstance === void 0) {
21525      deleteInstance = true;
21526    }
21527
21528    if (cleanStyles === void 0) {
21529      cleanStyles = true;
21530    }
21531
21532    var swiper = this;
21533    var params = swiper.params,
21534        $el = swiper.$el,
21535        $wrapperEl = swiper.$wrapperEl,
21536        slides = swiper.slides;
21537
21538    if (typeof swiper.params === 'undefined' || swiper.destroyed) {
21539      return null;
21540    }
21541
21542    swiper.emit('beforeDestroy'); // Init Flag
21543
21544    swiper.initialized = false; // Detach events
21545
21546    swiper.detachEvents(); // Destroy loop
21547
21548    if (params.loop) {
21549      swiper.loopDestroy();
21550    } // Cleanup styles
21551
21552
21553    if (cleanStyles) {
21554      swiper.removeClasses();
21555      $el.removeAttr('style');
21556      $wrapperEl.removeAttr('style');
21557
21558      if (slides && slides.length) {
21559        slides.removeClass([params.slideVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass].join(' ')).removeAttr('style').removeAttr('data-swiper-slide-index');
21560      }
21561    }
21562
21563    swiper.emit('destroy'); // Detach emitter events
21564
21565    Object.keys(swiper.eventsListeners).forEach(function (eventName) {
21566      swiper.off(eventName);
21567    });
21568
21569    if (deleteInstance !== false) {
21570      swiper.$el[0].swiper = null;
21571      Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["d" /* deleteProps */])(swiper);
21572    }
21573
21574    swiper.destroyed = true;
21575    return null;
21576  };
21577
21578  Swiper.extendDefaults = function extendDefaults(newDefaults) {
21579    Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])(extendedDefaults, newDefaults);
21580  };
21581
21582  Swiper.installModule = function installModule(module) {
21583    if (!Swiper.prototype.modules) Swiper.prototype.modules = {};
21584    var name = module.name || Object.keys(Swiper.prototype.modules).length + "_" + Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["i" /* now */])();
21585    Swiper.prototype.modules[name] = module;
21586  };
21587
21588  Swiper.use = function use(module) {
21589    if (Array.isArray(module)) {
21590      module.forEach(function (m) {
21591        return Swiper.installModule(m);
21592      });
21593      return Swiper;
21594    }
21595
21596    Swiper.installModule(module);
21597    return Swiper;
21598  };
21599
21600  _createClass(Swiper, null, [{
21601    key: "extendedDefaults",
21602    get: function get() {
21603      return extendedDefaults;
21604    }
21605  }, {
21606    key: "defaults",
21607    get: function get() {
21608      return __WEBPACK_IMPORTED_MODULE_22__defaults__["a" /* default */];
21609    }
21610  }]);
21611
21612  return Swiper;
21613}();
21614
21615Object.keys(prototypes).forEach(function (prototypeGroup) {
21616  Object.keys(prototypes[prototypeGroup]).forEach(function (protoMethod) {
21617    Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
21618  });
21619});
21620Swiper.use([__WEBPACK_IMPORTED_MODULE_6__modules_resize_resize__["a" /* default */], __WEBPACK_IMPORTED_MODULE_7__modules_observer_observer__["a" /* default */]]);
21621/* harmony default export */ __webpack_exports__["a"] = (Swiper);
21622
21623/***/ }),
21624/* 146 */
21625/***/ (function(module, __webpack_exports__, __webpack_require__) {
21626
21627"use strict";
21628/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return getSupport; });
21629/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
21630
21631var support;
21632
21633function calcSupport() {
21634  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
21635  var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
21636  return {
21637    touch: !!('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch),
21638    pointerEvents: !!window.PointerEvent && 'maxTouchPoints' in window.navigator && window.navigator.maxTouchPoints >= 0,
21639    observer: function checkObserver() {
21640      return 'MutationObserver' in window || 'WebkitMutationObserver' in window;
21641    }(),
21642    passiveListener: function checkPassiveListener() {
21643      var supportsPassive = false;
21644
21645      try {
21646        var opts = Object.defineProperty({}, 'passive', {
21647          // eslint-disable-next-line
21648          get: function get() {
21649            supportsPassive = true;
21650          }
21651        });
21652        window.addEventListener('testPassiveListener', null, opts);
21653      } catch (e) {// No support
21654      }
21655
21656      return supportsPassive;
21657    }(),
21658    gestures: function checkGestures() {
21659      return 'ongesturestart' in window;
21660    }()
21661  };
21662}
21663
21664function getSupport() {
21665  if (!support) {
21666    support = calcSupport();
21667  }
21668
21669  return support;
21670}
21671
21672
21673
21674/***/ }),
21675/* 147 */
21676/***/ (function(module, exports, __webpack_require__) {
21677
21678/* WEBPACK VAR INJECTION */(function(jQuery) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;    /*!
21679     * jQuery blockUI plugin
21680     * Version 2.70.0-2014.11.23
21681     * Requires jQuery v1.7 or later
21682     *
21683     * Examples at: http://malsup.com/jquery/block/
21684     * Copyright (c) 2007-2013 M. Alsup
21685     * Dual licensed under the MIT and GPL licenses:
21686     * http://www.opensource.org/licenses/mit-license.php
21687     * http://www.gnu.org/licenses/gpl.html
21688     *
21689     * Thanks to Amir-Hossein Sobhi for some excellent contributions!
21690     */
21691
21692    ; (function () {
21693        /*jshint eqeqeq:false curly:false latedef:false */
21694        "use strict";
21695
21696        function setup($) {
21697            $.fn._fadeIn = $.fn.fadeIn;
21698
21699            var noOp = $.noop || function () { };
21700
21701            // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
21702            // confusing userAgent strings on Vista)
21703            var msie = /MSIE/.test(navigator.userAgent);
21704            var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
21705            var mode = document.documentMode || 0;
21706            var setExpr = $.isFunction(document.createElement('div').style.setExpression);
21707
21708            // global $ methods for blocking/unblocking the entire page
21709            $.blockUI = function (opts) { install(window, opts); };
21710            $.unblockUI = function (opts) { remove(window, opts); };
21711
21712            // convenience method for quick growl-like notifications  (http://www.google.com/search?q=growl)
21713            $.growlUI = function (title, message, timeout, onClose, css) {
21714                var $m = $('<div class="growlUI"></div>');
21715                if (css == false) {
21716                    $m = $('<div class="growlUI_f"></div>');
21717                }
21718                if (title) $m.append('<h1>' + title + '</h1>');
21719                if (message) $m.append('<h2>' + message + '</h2>');
21720                if (timeout === undefined) timeout = 3000;
21721
vendor: 24,120 bytes, lines 21722-22253
21722                // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
21723                var callBlock = function (opts) {
21724                    opts = opts || {};
21725
21726                    $.blockUI({
21727                        message: $m,
21728                        fadeIn: typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700,
21729                        fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
21730                        timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
21731                        centerY: false,
21732                        showOverlay: false,
21733                        onUnblock: onClose,
21734                        css: $.blockUI.defaults.growlCSS
21735                    });
21736                };
21737
21738                callBlock();
21739                var nonmousedOpacity = $m.css('opacity');
21740                $m.mouseover(function () {
21741                    callBlock({
21742                        fadeIn: 0,
21743                        timeout: 30000
21744                    });
21745
21746                    var displayBlock = $('.blockMsg');
21747                    displayBlock.stop(); // cancel fadeout if it has started
21748                    displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
21749                }).mouseout(function () {
21750                    $('.blockMsg').fadeOut(1000);
21751                });
21752                // End konapun additions
21753            };
21754
21755            // plugin method for blocking element content
21756            $.fn.block = function (opts) {
21757                if (this[0] === window) {
21758                    $.blockUI(opts);
21759                    return this;
21760                }
21761                var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
21762                this.each(function () {
21763                    var $el = $(this);
21764                    if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
21765                        return;
21766                    $el.unblock({ fadeOut: 0 });
21767                });
21768
21769                return this.each(function () {
21770                    if ($.css(this, 'position') == 'static') {
21771                        this.style.position = 'relative';
21772                        $(this).data('blockUI.static', true);
21773                    }
21774                    this.style.zoom = 1; // force 'hasLayout' in ie
21775                    install(this, opts);
21776                });
21777            };
21778
21779            // plugin method for unblocking element content
21780            $.fn.unblock = function (opts) {
21781                if (this[0] === window) {
21782                    $.unblockUI(opts);
21783                    return this;
21784                }
21785                return this.each(function () {
21786                    remove(this, opts);
21787                });
21788            };
21789
21790            $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
21791
21792            // override these in your code to change the default behavior and style
21793            $.blockUI.defaults = {
21794                // message displayed when blocking (use null for no message)
21795                message: '<h1>Please wait...</h1>',
21796
21797                title: null,		// title string; only used when theme == true
21798                draggable: true,	// only used when theme == true (requires jquery-ui.js to be loaded)
21799
21800                theme: false, // set to true to use with jQuery UI themes
21801
21802                // styles for the message when blocking; if you wish to disable
21803                // these and use an external stylesheet then do this in your code:
21804                // $.blockUI.defaults.css = {};
21805                css: {
21806                    padding: 0,
21807                    margin: 0,
21808                    width: '30%',
21809                    top: '40%',
21810                    left: '35%',
21811                    textAlign: 'center',
21812                    color: '#000',
21813                    border: '3px solid #aaa',
21814                    backgroundColor: '#fff',
21815                    cursor: 'wait'
21816                },
21817
21818                // minimal style set used when themes are used
21819                themedCSS: {
21820                    width: '30%',
21821                    top: '40%',
21822                    left: '35%'
21823                },
21824
21825                // styles for the overlay
21826                overlayCSS: {
21827                    backgroundColor: '#000',
21828                    opacity: 0.6,
21829                    cursor: 'wait'
21830                },
21831
21832                // style to replace wait cursor before unblocking to correct issue
21833                // of lingering wait cursor
21834                cursorReset: 'default',
21835
21836                // styles applied when using $.growlUI
21837                growlCSS: {
21838                    width: '350px',
21839                    top: '10px',
21840                    left: '',
21841                    right: '10px',
21842                    border: 'none',
21843                    padding: '5px',
21844                    opacity: 0.6,
21845                    cursor: 'default',
21846                    color: '#fff',
21847                    backgroundColor: '#000',
21848                    '-webkit-border-radius': '10px',
21849                    '-moz-border-radius': '10px',
21850                    'border-radius': '10px'
21851                },
21852
21853                // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
21854                // (hat tip to Jorge H. N. de Vasconcelos)
21855                /*jshint scripturl:true */
21856                iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
21857
21858                // force usage of iframe in non-IE browsers (handy for blocking applets)
21859                forceIframe: false,
21860
21861                // z-index for the blocking overlay
21862                baseZ: 1000,
21863
21864                // set these to true to have the message automatically centered
21865                centerX: true, // <-- only effects element blocking (page block controlled via css above)
21866                centerY: true,
21867
21868                // allow body element to be stetched in ie6; this makes blocking look better
21869                // on "short" pages.  disable if you wish to prevent changes to the body height
21870                allowBodyStretch: true,
21871
21872                // enable if you want key and mouse events to be disabled for content that is blocked
21873                bindEvents: true,
21874
21875                // be default blockUI will supress tab navigation from leaving blocking content
21876                // (if bindEvents is true)
21877                constrainTabKey: true,
21878
21879                // fadeIn time in millis; set to 0 to disable fadeIn on block
21880                fadeIn: 200,
21881
21882                // fadeOut time in millis; set to 0 to disable fadeOut on unblock
21883                fadeOut: 400,
21884
21885                // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
21886                timeout: 0,
21887
21888                // disable if you don't want to show the overlay
21889                showOverlay: true,
21890
21891                // if true, focus will be placed in the first available input field when
21892                // page blocking
21893                focusInput: true,
21894
21895                // elements that can receive focus
21896                focusableElements: ':input:enabled:visible',
21897
21898                // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
21899                // no longer needed in 2012
21900                // applyPlatformOpacityRules: true,
21901
21902                // callback method invoked when fadeIn has completed and blocking message is visible
21903                onBlock: null,
21904
21905                // callback method invoked when unblocking has completed; the callback is
21906                // passed the element that has been unblocked (which is the window object for page
21907                // blocks) and the options that were passed to the unblock call:
21908                //	onUnblock(element, options)
21909                onUnblock: null,
21910
21911                // callback method invoked when the overlay area is clicked.
21912                // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
21913                onOverlayClick: null,
21914
21915                // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
21916                quirksmodeOffsetHack: 4,
21917
21918                // class name of the message block
21919                blockMsgClass: 'blockMsg',
21920
21921                // if it is already blocked, then ignore it (don't unblock and reblock)
21922                ignoreIfBlocked: false
21923            };
21924
21925            // private data and functions follow...
21926
21927            var pageBlock = null;
21928            var pageBlockEls = [];
21929
21930            function install(el, opts) {
21931                var css, themedCSS;
21932                var full = (el == window);
21933                var msg = (opts && opts.message !== undefined ? opts.message : undefined);
21934                opts = $.extend({}, $.blockUI.defaults, opts || {});
21935
21936                if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
21937                    return;
21938
21939                opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
21940                css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
21941                if (opts.onOverlayClick)
21942                    opts.overlayCSS.cursor = 'pointer';
21943
21944                themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
21945                msg = msg === undefined ? opts.message : msg;
21946
21947                // remove the current block (if there is one)
21948                if (full && pageBlock)
21949                    remove(window, { fadeOut: 0 });
21950
21951                // if an existing element is being used as the blocking content then we capture
21952                // its current place in the DOM (and current display style) so we can restore
21953                // it when we unblock
21954                if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
21955                    var node = msg.jquery ? msg[0] : msg;
21956                    var data = {};
21957                    $(el).data('blockUI.history', data);
21958                    data.el = node;
21959                    data.parent = node.parentNode;
21960                    data.display = node.style.display;
21961                    data.position = node.style.position;
21962                    if (data.parent)
21963                        data.parent.removeChild(node);
21964                }
21965
21966                $(el).data('blockUI.onUnblock', opts.onUnblock);
21967                var z = opts.baseZ;
21968
21969                // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
21970                // layer1 is the iframe layer which is used to supress bleed through of underlying content
21971                // layer2 is the overlay layer which has opacity and a wait cursor (by default)
21972                // layer3 is the message content that is displayed while blocking
21973                var lyr1, lyr2, lyr3, s;
21974                if (msie || opts.forceIframe)
21975                    lyr1 = $('<iframe class="blockUI" style="z-index:' + (z++) + ';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="' + opts.iframeSrc + '"></iframe>');
21976                else
21977                    lyr1 = $('<div class="blockUI" style="display:none"></div>');
21978
21979                if (opts.theme)
21980                    lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:' + (z++) + ';display:none"></div>');
21981                else
21982                    lyr2 = $('<div class="blockUI blockOverlay" style="z-index:' + (z++) + ';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
21983
21984                if (opts.theme && full) {
21985                    s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:' + (z + 10) + ';display:none;position:fixed">';
21986                    if (opts.title) {
21987                        s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">' + (opts.title || '&nbsp;') + '</div>';
21988                    }
21989                    s += '<div class="ui-widget-content ui-dialog-content"></div>';
21990                    s += '</div>';
21991                }
21992                else if (opts.theme) {
21993                    s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:' + (z + 10) + ';display:none;position:absolute">';
21994                    if (opts.title) {
21995                        s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">' + (opts.title || '&nbsp;') + '</div>';
21996                    }
21997                    s += '<div class="ui-widget-content ui-dialog-content"></div>';
21998                    s += '</div>';
21999                }
22000                else if (full) {
22001                    s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:' + (z + 10) + ';display:none;position:fixed"></div>';
22002                }
22003                else {
22004                    s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:' + (z + 10) + ';display:none;position:absolute"></div>';
22005                }
22006                lyr3 = $(s);
22007
22008                // if we have a message, style it
22009                if (msg) {
22010                    if (opts.theme) {
22011                        lyr3.css(themedCSS);
22012                        lyr3.addClass('ui-widget-content');
22013                    }
22014                    else
22015                        lyr3.css(css);
22016                }
22017
22018                // style the overlay
22019                if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
22020                    lyr2.css(opts.overlayCSS);
22021                lyr2.css('position', full ? 'fixed' : 'absolute');
22022
22023                // make iframe layer transparent in IE
22024                if (msie || opts.forceIframe)
22025                    lyr1.css('opacity', 0.0);
22026
22027                //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
22028                var layers = [lyr1, lyr2, lyr3], $par = full ? $('body') : $(el);
22029                $.each(layers, function () {
22030                    this.appendTo($par);
22031                });
22032
22033                if (opts.theme && opts.draggable && $.fn.draggable) {
22034                    lyr3.draggable({
22035                        handle: '.ui-dialog-titlebar',
22036                        cancel: 'li'
22037                    });
22038                }
22039
22040                // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
22041                var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
22042                if (ie6 || expr) {
22043                    // give body 100% height
22044                    if (full && opts.allowBodyStretch && $.support.boxModel)
22045                        $('html,body').css('height', '100%');
22046
22047                    // fix ie6 issue when blocked element has a border width
22048                    if ((ie6 || !$.support.boxModel) && !full) {
22049                        var t = sz(el, 'borderTopWidth'), l = sz(el, 'borderLeftWidth');
22050                        var fixT = t ? '(0 - ' + t + ')' : 0;
22051                        var fixL = l ? '(0 - ' + l + ')' : 0;
22052                    }
22053
22054                    // simulate fixed position
22055                    $.each(layers, function (i, o) {
22056                        var s = o[0].style;
22057                        s.position = 'absolute';
22058                        if (i < 2) {
22059                            if (full)
22060                                s.setExpression('height', 'Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:' + opts.quirksmodeOffsetHack + ') + "px"');
22061                            else
22062                                s.setExpression('height', 'this.parentNode.offsetHeight + "px"');
22063                            if (full)
22064                                s.setExpression('width', 'jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
22065                            else
22066                                s.setExpression('width', 'this.parentNode.offsetWidth + "px"');
22067                            if (fixL) s.setExpression('left', fixL);
22068                            if (fixT) s.setExpression('top', fixT);
22069                        }
22070                        else if (opts.centerY) {
22071                            if (full) s.setExpression('top', '(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
22072                            s.marginTop = 0;
22073                        }
22074                        else if (!opts.centerY && full) {
22075                            var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
22076                            var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + ' + top + ') + "px"';
22077                            s.setExpression('top', expression);
22078                        }
22079                    });
22080                }
22081
22082                // show the message
22083                if (msg) {
22084                    if (opts.theme)
22085                        lyr3.find('.ui-widget-content').append(msg);
22086                    else
22087                        lyr3.append(msg);
22088                    if (msg.jquery || msg.nodeType)
22089                        $(msg).show();
22090                }
22091
22092                if ((msie || opts.forceIframe) && opts.showOverlay)
22093                    lyr1.show(); // opacity is zero
22094                if (opts.fadeIn) {
22095                    var cb = opts.onBlock ? opts.onBlock : noOp;
22096                    var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
22097                    var cb2 = msg ? cb : noOp;
22098                    if (opts.showOverlay)
22099                        lyr2._fadeIn(opts.fadeIn, cb1);
22100                    if (msg)
22101                        lyr3._fadeIn(opts.fadeIn, cb2);
22102                }
22103                else {
22104                    if (opts.showOverlay)
22105                        lyr2.show();
22106                    if (msg)
22107                        lyr3.show();
22108                    if (opts.onBlock)
22109                        opts.onBlock.bind(lyr3)();
22110                }
22111
22112                // bind key and mouse events
22113                bind(1, el, opts);
22114
22115                if (full) {
22116                    pageBlock = lyr3[0];
22117                    pageBlockEls = $(opts.focusableElements, pageBlock);
22118                    if (opts.focusInput)
22119                        setTimeout(focus, 20);
22120                }
22121                else
22122                    center(lyr3[0], opts.centerX, opts.centerY);
22123
22124                if (opts.timeout) {
22125                    // auto-unblock
22126                    var to = setTimeout(function () {
22127                        if (full)
22128                            $.unblockUI(opts);
22129                        else
22130                            $(el).unblock(opts);
22131                    }, opts.timeout);
22132                    $(el).data('blockUI.timeout', to);
22133                }
22134            }
22135
22136            // remove the block
22137            function remove(el, opts) {
22138                var count;
22139                var full = (el == window);
22140                var $el = $(el);
22141                var data = $el.data('blockUI.history');
22142                var to = $el.data('blockUI.timeout');
22143                if (to) {
22144                    clearTimeout(to);
22145                    $el.removeData('blockUI.timeout');
22146                }
22147                opts = $.extend({}, $.blockUI.defaults, opts || {});
22148                bind(0, el, opts); // unbind events
22149
22150                if (opts.onUnblock === null) {
22151                    opts.onUnblock = $el.data('blockUI.onUnblock');
22152                    $el.removeData('blockUI.onUnblock');
22153                }
22154
22155                var els;
22156                if (full) // crazy selector to handle odd field errors in ie6/7
22157                    els = $('body').children().filter('.blockUI').add('body > .blockUI');
22158                else
22159                    els = $el.find('>.blockUI');
22160
22161                // fix cursor issue
22162                if (opts.cursorReset) {
22163                    if (els.length > 1)
22164                        els[1].style.cursor = opts.cursorReset;
22165                    if (els.length > 2)
22166                        els[2].style.cursor = opts.cursorReset;
22167                }
22168
22169                if (full)
22170                    pageBlock = pageBlockEls = null;
22171
22172                if (opts.fadeOut) {
22173                    count = els.length;
22174                    els.stop().fadeOut(opts.fadeOut, function () {
22175                        if (--count === 0)
22176                            reset(els, data, opts, el);
22177                    });
22178                }
22179                else
22180                    reset(els, data, opts, el);
22181            }
22182
22183            // move blocking element back into the DOM where it started
22184            function reset(els, data, opts, el) {
22185                var $el = $(el);
22186                if ($el.data('blockUI.isBlocked'))
22187                    return;
22188
22189                els.each(function (i, o) {
22190                    // remove via DOM calls so we don't lose event handlers
22191                    if (this.parentNode)
22192                        this.parentNode.removeChild(this);
22193                });
22194
22195                if (data && data.el) {
22196                    data.el.style.display = data.display;
22197                    data.el.style.position = data.position;
22198                    data.el.style.cursor = 'default'; // #59
22199                    if (data.parent)
22200                        data.parent.appendChild(data.el);
22201                    $el.removeData('blockUI.history');
22202                }
22203
22204                if ($el.data('blockUI.static')) {
22205                    $el.css('position', 'static'); // #22
22206                }
22207
22208                if (typeof opts.onUnblock == 'function')
22209                    opts.onUnblock(el, opts);
22210
22211                // fix issue in Safari 6 where block artifacts remain until reflow
22212                var body = $(document.body), w = body.width(), cssW = body[0].style.width;
22213                body.width(w - 1).width(w);
22214                body[0].style.width = cssW;
22215            }
22216
22217            // bind/unbind the handler
22218            function bind(b, el, opts) {
22219                var full = el == window, $el = $(el);
22220
22221                // don't bother unbinding if there is nothing to unbind
22222                if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
22223                    return;
22224
22225                $el.data('blockUI.isBlocked', b);
22226
22227                // don't bind events when overlay is not in use or if bindEvents is false
22228                if (!full || !opts.bindEvents || (b && !opts.showOverlay))
22229                    return;
22230
22231                // bind anchors and inputs for mouse and key events
22232                var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
22233                if (b)
22234                    $(document).bind(events, opts, handler);
22235                else
22236                    $(document).unbind(events, handler);
22237
22238                // former impl...
22239                //		var $e = $('a,:input');
22240                //		b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
22241            }
22242
22243            // event handler to suppress keyboard/mouse events when blocking
22244            function handler(e) {
22245                // allow tab navigation (conditionally)
22246                if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
22247                    if (pageBlock && e.data.constrainTabKey) {
22248                        var els = pageBlockEls;
22249                        var fwd = !e.shiftKey && e.target === els[els.length - 1];
22250                        var back = e.shiftKey && e.target === els[0];
22251                        if (fwd || back) {
22252                            setTimeout(function () { focus(back); }, 10);
22253                            return false;
22254                        }
22255                    }
22256                }
22257                var opts = e.data;
22258                var target = $(e.target);
22259                if (target.hasClass('blockOverlay') && opts.onOverlayClick)
22260                    opts.onOverlayClick(e);
22261
22262                // allow events within the message content
22263                if (target.parents('div.' + opts.blockMsgClass).length > 0)
22264                    return true;
22265
22266                // allow events for content that is not being blocked
22267                return target.parents().children().filter('div.blockUI').length === 0;
22268            }
22269
22270            function focus(back) {
22271                if (!pageBlockEls)
22272                    return;
22273                var e = pageBlockEls[back === true ? pageBlockEls.length - 1 : 0];
22274                if (e)
22275                    e.focus();
22276            }
22277
22278            function center(el, x, y) {
22279                var p = el.parentNode, s = el.style;
22280                var l = ((p.offsetWidth - el.offsetWidth) / 2) - sz(p, 'borderLeftWidth');
22281                var t = ((p.offsetHeight - el.offsetHeight) / 2) - sz(p, 'borderTopWidth');
22282                if (x) s.left = l > 0 ? (l + 'px') : '0';
22283                if (y) s.top = t > 0 ? (t + 'px') : '0';
22284            }
22285
22286            function sz(el, p) {
22287                return parseInt($.css(el, p), 10) || 0;
22288            }
22289
22290        }
22291
22292
22293        /*global define:true */
22294        if ("function" === 'function' && __webpack_require__(148) && __webpack_require__(148).jQuery) {
22295            !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(2)], __WEBPACK_AMD_DEFINE_FACTORY__ = (setup),
22296				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
22297				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
22298				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
22299        } else {
22300            setup(jQuery);
22301        }
22302
22303    })();
22304/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2)))
22305
22306/***/ }),
22307/* 148 */
22308/***/ (function(module, exports) {
22309
22310/* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {/* globals __webpack_amd_options__ */
22311module.exports = __webpack_amd_options__;
22312
22313/* WEBPACK VAR INJECTION */}.call(exports, {}))
22314
22315/***/ }),
22316/* 149 */
22317/***/ (function(module, exports, __webpack_require__) {
22318
22319/* WEBPACK VAR INJECTION */(function($) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;var require;var require;/*!
22320 * Select2 4.1.0-rc.0
22321 * https://select2.github.io
22322 *
22323 * Released under the MIT license
22324 * https://github.com/select2/select2/blob/master/LICENSE.md
22325 */
22326;(function (factory) {
22327  if (true) {
22328    // AMD. Register as an anonymous module.
22329    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(2)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
22330				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
22331				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
22332				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)
vendor: 18,847 bytes, lines 22332-22898
22332);
22333  } else if (typeof module === 'object' && module.exports) {
22334    // Node/CommonJS
22335    module.exports = function (root, jQuery) {
22336      if (jQuery === undefined) {
22337        // require('jQuery') returns a factory that requires window to
22338        // build a jQuery instance, we normalize how we use modules
22339        // that require this pattern but the window provided is a noop
22340        // if it's defined (how jquery works)
22341        if (typeof window !== 'undefined') {
22342          jQuery = require('jquery');
22343        }
22344        else {
22345          jQuery = require('jquery')(root);
22346        }
22347      }
22348      factory(jQuery);
22349      return jQuery;
22350    };
22351  } else {
22352    // Browser globals
22353    factory(jQuery);
22354  }
22355} (function (jQuery) {
22356  // This is needed so we can catch the AMD loader configuration and use it
22357  // The inner file should be wrapped (by `banner.start.js`) in a function that
22358  // returns the AMD loader references.
22359  var S2 =(function () {
22360  // Restore the Select2 AMD loader so it can be used
22361  // Needed mostly in the language files, where the loader is not inserted
22362  if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
22363    var S2 = jQuery.fn.select2.amd;
22364  }
22365var S2;(function () { if (!S2 || !S2.requirejs) {
22366if (!S2) { S2 = {}; } else { require = S2; }
22367/**
22368 * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
22369 * Released under MIT license, http://github.com/requirejs/almond/LICENSE
22370 */
22371//Going sloppy to avoid 'use strict' string cost, but strict practices should
22372//be followed.
22373/*global setTimeout: false */
22374
22375var requirejs, require, define;
22376(function (undef) {
22377    var main, req, makeMap, handlers,
22378        defined = {},
22379        waiting = {},
22380        config = {},
22381        defining = {},
22382        hasOwn = Object.prototype.hasOwnProperty,
22383        aps = [].slice,
22384        jsSuffixRegExp = /\.js$/;
22385
22386    function hasProp(obj, prop) {
22387        return hasOwn.call(obj, prop);
22388    }
22389
22390    /**
22391     * Given a relative module name, like ./something, normalize it to
22392     * a real name that can be mapped to a path.
22393     * @param {String} name the relative name
22394     * @param {String} baseName a real name that the name arg is relative
22395     * to.
22396     * @returns {String} normalized name
22397     */
22398    function normalize(name, baseName) {
22399        var nameParts, nameSegment, mapValue, foundMap, lastIndex,
22400            foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
22401            baseParts = baseName && baseName.split("/"),
22402            map = config.map,
22403            starMap = (map && map['*']) || {};
22404
22405        //Adjust any relative paths.
22406        if (name) {
22407            name = name.split('/');
22408            lastIndex = name.length - 1;
22409
22410            // If wanting node ID compatibility, strip .js from end
22411            // of IDs. Have to do this here, and not in nameToUrl
22412            // because node allows either .js or non .js to map
22413            // to same file.
22414            if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
22415                name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
22416            }
22417
22418            // Starts with a '.' so need the baseName
22419            if (name[0].charAt(0) === '.' && baseParts) {
22420                //Convert baseName to array, and lop off the last part,
22421                //so that . matches that 'directory' and not name of the baseName's
22422                //module. For instance, baseName of 'one/two/three', maps to
22423                //'one/two/three.js', but we want the directory, 'one/two' for
22424                //this normalization.
22425                normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
22426                name = normalizedBaseParts.concat(name);
22427            }
22428
22429            //start trimDots
22430            for (i = 0; i < name.length; i++) {
22431                part = name[i];
22432                if (part === '.') {
22433                    name.splice(i, 1);
22434                    i -= 1;
22435                } else if (part === '..') {
22436                    // If at the start, or previous value is still ..,
22437                    // keep them so that when converted to a path it may
22438                    // still work when converted to a path, even though
22439                    // as an ID it is less than ideal. In larger point
22440                    // releases, may be better to just kick out an error.
22441                    if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
22442                        continue;
22443                    } else if (i > 0) {
22444                        name.splice(i - 1, 2);
22445                        i -= 2;
22446                    }
22447                }
22448            }
22449            //end trimDots
22450
22451            name = name.join('/');
22452        }
22453
22454        //Apply map config if available.
22455        if ((baseParts || starMap) && map) {
22456            nameParts = name.split('/');
22457
22458            for (i = nameParts.length; i > 0; i -= 1) {
22459                nameSegment = nameParts.slice(0, i).join("/");
22460
22461                if (baseParts) {
22462                    //Find the longest baseName segment match in the config.
22463                    //So, do joins on the biggest to smallest lengths of baseParts.
22464                    for (j = baseParts.length; j > 0; j -= 1) {
22465                        mapValue = map[baseParts.slice(0, j).join('/')];
22466
22467                        //baseName segment has  config, find if it has one for
22468                        //this name.
22469                        if (mapValue) {
22470                            mapValue = mapValue[nameSegment];
22471                            if (mapValue) {
22472                                //Match, update name to the new value.
22473                                foundMap = mapValue;
22474                                foundI = i;
22475                                break;
22476                            }
22477                        }
22478                    }
22479                }
22480
22481                if (foundMap) {
22482                    break;
22483                }
22484
22485                //Check for a star map match, but just hold on to it,
22486                //if there is a shorter segment match later in a matching
22487                //config, then favor over this star map.
22488                if (!foundStarMap && starMap && starMap[nameSegment]) {
22489                    foundStarMap = starMap[nameSegment];
22490                    starI = i;
22491                }
22492            }
22493
22494            if (!foundMap && foundStarMap) {
22495                foundMap = foundStarMap;
22496                foundI = starI;
22497            }
22498
22499            if (foundMap) {
22500                nameParts.splice(0, foundI, foundMap);
22501                name = nameParts.join('/');
22502            }
22503        }
22504
22505        return name;
22506    }
22507
22508    function makeRequire(relName, forceSync) {
22509        return function () {
22510            //A version of a require function that passes a moduleName
22511            //value for items that may need to
22512            //look up paths relative to the moduleName
22513            var args = aps.call(arguments, 0);
22514
22515            //If first arg is not require('string'), and there is only
22516            //one arg, it is the array form without a callback. Insert
22517            //a null so that the following concat is correct.
22518            if (typeof args[0] !== 'string' && args.length === 1) {
22519                args.push(null);
22520            }
22521            return req.apply(undef, args.concat([relName, forceSync]));
22522        };
22523    }
22524
22525    function makeNormalize(relName) {
22526        return function (name) {
22527            return normalize(name, relName);
22528        };
22529    }
22530
22531    function makeLoad(depName) {
22532        return function (value) {
22533            defined[depName] = value;
22534        };
22535    }
22536
22537    function callDep(name) {
22538        if (hasProp(waiting, name)) {
22539            var args = waiting[name];
22540            delete waiting[name];
22541            defining[name] = true;
22542            main.apply(undef, args);
22543        }
22544
22545        if (!hasProp(defined, name) && !hasProp(defining, name)) {
22546            throw new Error('No ' + name);
22547        }
22548        return defined[name];
22549    }
22550
22551    //Turns a plugin!resource to [plugin, resource]
22552    //with the plugin being undefined if the name
22553    //did not have a plugin prefix.
22554    function splitPrefix(name) {
22555        var prefix,
22556            index = name ? name.indexOf('!') : -1;
22557        if (index > -1) {
22558            prefix = name.substring(0, index);
22559            name = name.substring(index + 1, name.length);
22560        }
22561        return [prefix, name];
22562    }
22563
22564    //Creates a parts array for a relName where first part is plugin ID,
22565    //second part is resource ID. Assumes relName has already been normalized.
22566    function makeRelParts(relName) {
22567        return relName ? splitPrefix(relName) : [];
22568    }
22569
22570    /**
22571     * Makes a name map, normalizing the name, and using a plugin
22572     * for normalization if necessary. Grabs a ref to plugin
22573     * too, as an optimization.
22574     */
22575    makeMap = function (name, relParts) {
22576        var plugin,
22577            parts = splitPrefix(name),
22578            prefix = parts[0],
22579            relResourceName = relParts[1];
22580
22581        name = parts[1];
22582
22583        if (prefix) {
22584            prefix = normalize(prefix, relResourceName);
22585            plugin = callDep(prefix);
22586        }
22587
22588        //Normalize according
22589        if (prefix) {
22590            if (plugin && plugin.normalize) {
22591                name = plugin.normalize(name, makeNormalize(relResourceName));
22592            } else {
22593                name = normalize(name, relResourceName);
22594            }
22595        } else {
22596            name = normalize(name, relResourceName);
22597            parts = splitPrefix(name);
22598            prefix = parts[0];
22599            name = parts[1];
22600            if (prefix) {
22601                plugin = callDep(prefix);
22602            }
22603        }
22604
22605        //Using ridiculous property names for space reasons
22606        return {
22607            f: prefix ? prefix + '!' + name : name, //fullName
22608            n: name,
22609            pr: prefix,
22610            p: plugin
22611        };
22612    };
22613
22614    function makeConfig(name) {
22615        return function () {
22616            return (config && config.config && config.config[name]) || {};
22617        };
22618    }
22619
22620    handlers = {
22621        require: function (name) {
22622            return makeRequire(name);
22623        },
22624        exports: function (name) {
22625            var e = defined[name];
22626            if (typeof e !== 'undefined') {
22627                return e;
22628            } else {
22629                return (defined[name] = {});
22630            }
22631        },
22632        module: function (name) {
22633            return {
22634                id: name,
22635                uri: '',
22636                exports: defined[name],
22637                config: makeConfig(name)
22638            };
22639        }
22640    };
22641
22642    main = function (name, deps, callback, relName) {
22643        var cjsModule, depName, ret, map, i, relParts,
22644            args = [],
22645            callbackType = typeof callback,
22646            usingExports;
22647
22648        //Use name if no relName
22649        relName = relName || name;
22650        relParts = makeRelParts(relName);
22651
22652        //Call the callback to define the module, if necessary.
22653        if (callbackType === 'undefined' || callbackType === 'function') {
22654            //Pull out the defined dependencies and pass the ordered
22655            //values to the callback.
22656            //Default to [require, exports, module] if no deps
22657            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
22658            for (i = 0; i < deps.length; i += 1) {
22659                map = makeMap(deps[i], relParts);
22660                depName = map.f;
22661
22662                //Fast path CommonJS standard dependencies.
22663                if (depName === "require") {
22664                    args[i] = handlers.require(name);
22665                } else if (depName === "exports") {
22666                    //CommonJS module spec 1.1
22667                    args[i] = handlers.exports(name);
22668                    usingExports = true;
22669                } else if (depName === "module") {
22670                    //CommonJS module spec 1.1
22671                    cjsModule = args[i] = handlers.module(name);
22672                } else if (hasProp(defined, depName) ||
22673                           hasProp(waiting, depName) ||
22674                           hasProp(defining, depName)) {
22675                    args[i] = callDep(depName);
22676                } else if (map.p) {
22677                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
22678                    args[i] = defined[depName];
22679                } else {
22680                    throw new Error(name + ' missing ' + depName);
22681                }
22682            }
22683
22684            ret = callback ? callback.apply(defined[name], args) : undefined;
22685
22686            if (name) {
22687                //If setting exports via "module" is in play,
22688                //favor that over return value and exports. After that,
22689                //favor a non-undefined return value over exports use.
22690                if (cjsModule && cjsModule.exports !== undef &&
22691                        cjsModule.exports !== defined[name]) {
22692                    defined[name] = cjsModule.exports;
22693                } else if (ret !== undef || !usingExports) {
22694                    //Use the return value from the function.
22695                    defined[name] = ret;
22696                }
22697            }
22698        } else if (name) {
22699            //May just be an object definition for the module. Only
22700            //worry about defining if have a module name.
22701            defined[name] = callback;
22702        }
22703    };
22704
22705    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
22706        if (typeof deps === "string") {
22707            if (handlers[deps]) {
22708                //callback in this case is really relName
22709                return handlers[deps](callback);
22710            }
22711            //Just return the module wanted. In this scenario, the
22712            //deps arg is the module name, and second arg (if passed)
22713            //is just the relName.
22714            //Normalize module name, if it contains . or ..
22715            return callDep(makeMap(deps, makeRelParts(callback)).f);
22716        } else if (!deps.splice) {
22717            //deps is a config object, not an array.
22718            config = deps;
22719            if (config.deps) {
22720                req(config.deps, config.callback);
22721            }
22722            if (!callback) {
22723                return;
22724            }
22725
22726            if (callback.splice) {
22727                //callback is an array, which means it is a dependency list.
22728                //Adjust args if there are dependencies
22729                deps = callback;
22730                callback = relName;
22731                relName = null;
22732            } else {
22733                deps = undef;
22734            }
22735        }
22736
22737        //Support require(['a'])
22738        callback = callback || function () {};
22739
22740        //If relName is a function, it is an errback handler,
22741        //so remove it.
22742        if (typeof relName === 'function') {
22743            relName = forceSync;
22744            forceSync = alt;
22745        }
22746
22747        //Simulate async callback;
22748        if (forceSync) {
22749            main(undef, deps, callback, relName);
22750        } else {
22751            //Using a non-zero value because of concern for what old browsers
22752            //do, and latest browsers "upgrade" to 4 if lower value is used:
22753            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
22754            //If want a value immediately, use require('id') instead -- something
22755            //that works in almond on the global level, but not guaranteed and
22756            //unlikely to work in other AMD implementations.
22757            setTimeout(function () {
22758                main(undef, deps, callback, relName);
22759            }, 4);
22760        }
22761
22762        return req;
22763    };
22764
22765    /**
22766     * Just drops the config on the floor, but returns req in case
22767     * the config return value is used.
22768     */
22769    req.config = function (cfg) {
22770        return req(cfg);
22771    };
22772
22773    /**
22774     * Expose module registry for debugging and tooling
22775     */
22776    requirejs._defined = defined;
22777
22778    define = function (name, deps, callback) {
22779        if (typeof name !== 'string') {
22780            throw new Error('See almond README: incorrect module build, no module name');
22781        }
22782
22783        //This module may not have dependencies
22784        if (!deps.splice) {
22785            //deps is not an array, so probably means
22786            //an object literal or factory function for
22787            //the value. Adjust args.
22788            callback = deps;
22789            deps = [];
22790        }
22791
22792        if (!hasProp(defined, name) && !hasProp(waiting, name)) {
22793            waiting[name] = [name, deps, callback];
22794        }
22795    };
22796
22797    define.amd = {
22798        jQuery: true
22799    };
22800}());
22801
22802S2.requirejs = requirejs;S2.require = require;S2.define = define;
22803}
22804}());
22805S2.define("almond", function(){});
22806
22807/* global jQuery:false, $:false */
22808S2.define('jquery',[],function () {
22809  var _$ = jQuery || $;
22810
22811  if (_$ == null && console && console.error) {
22812    console.error(
22813      'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
22814      'found. Make sure that you are including jQuery before Select2 on your ' +
22815      'web page.'
22816    );
22817  }
22818
22819  return _$;
22820});
22821
22822S2.define('select2/utils',[
22823  'jquery'
22824], function ($) {
22825  var Utils = {};
22826
22827  Utils.Extend = function (ChildClass, SuperClass) {
22828    var __hasProp = {}.hasOwnProperty;
22829
22830    function BaseConstructor () {
22831      this.constructor = ChildClass;
22832    }
22833
22834    for (var key in SuperClass) {
22835      if (__hasProp.call(SuperClass, key)) {
22836        ChildClass[key] = SuperClass[key];
22837      }
22838    }
22839
22840    BaseConstructor.prototype = SuperClass.prototype;
22841    ChildClass.prototype = new BaseConstructor();
22842    ChildClass.__super__ = SuperClass.prototype;
22843
22844    return ChildClass;
22845  };
22846
22847  function getMethods (theClass) {
22848    var proto = theClass.prototype;
22849
22850    var methods = [];
22851
22852    for (var methodName in proto) {
22853      var m = proto[methodName];
22854
22855      if (typeof m !== 'function') {
22856        continue;
22857      }
22858
22859      if (methodName === 'constructor') {
22860        continue;
22861      }
22862
22863      methods.push(methodName);
22864    }
22865
22866    return methods;
22867  }
22868
22869  Utils.Decorate = function (SuperClass, DecoratorClass) {
22870    var decoratedMethods = getMethods(DecoratorClass);
22871    var superMethods = getMethods(SuperClass);
22872
22873    function DecoratedClass () {
22874      var unshift = Array.prototype.unshift;
22875
22876      var argCount = DecoratorClass.prototype.constructor.length;
22877
22878      var calledConstructor = SuperClass.prototype.constructor;
22879
22880      if (argCount > 0) {
22881        unshift.call(arguments, SuperClass.prototype.constructor);
22882
22883        calledConstructor = DecoratorClass.prototype.constructor;
22884      }
22885
22886      calledConstructor.apply(this, arguments);
22887    }
22888
22889    DecoratorClass.displayName = SuperClass.displayName;
22890
22891    function ctr () {
22892      this.constructor = DecoratedClass;
22893    }
22894
22895    DecoratedClass.prototype = new ctr();
22896
22897    for (var m = 0; m < superMethods.length; m++) {
22898      
vendor: 102,497 bytes, lines 22898-27170
22898var superMethod = superMethods[m];
22899
22900      DecoratedClass.prototype[superMethod] =
22901        SuperClass.prototype[superMethod];
22902    }
22903
22904    var calledMethod = function (methodName) {
22905      // Stub out the original method if it's not decorating an actual method
22906      var originalMethod = function () {};
22907
22908      if (methodName in DecoratedClass.prototype) {
22909        originalMethod = DecoratedClass.prototype[methodName];
22910      }
22911
22912      var decoratedMethod = DecoratorClass.prototype[methodName];
22913
22914      return function () {
22915        var unshift = Array.prototype.unshift;
22916
22917        unshift.call(arguments, originalMethod);
22918
22919        return decoratedMethod.apply(this, arguments);
22920      };
22921    };
22922
22923    for (var d = 0; d < decoratedMethods.length; d++) {
22924      var decoratedMethod = decoratedMethods[d];
22925
22926      DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
22927    }
22928
22929    return DecoratedClass;
22930  };
22931
22932  var Observable = function () {
22933    this.listeners = {};
22934  };
22935
22936  Observable.prototype.on = function (event, callback) {
22937    this.listeners = this.listeners || {};
22938
22939    if (event in this.listeners) {
22940      this.listeners[event].push(callback);
22941    } else {
22942      this.listeners[event] = [callback];
22943    }
22944  };
22945
22946  Observable.prototype.trigger = function (event) {
22947    var slice = Array.prototype.slice;
22948    var params = slice.call(arguments, 1);
22949
22950    this.listeners = this.listeners || {};
22951
22952    // Params should always come in as an array
22953    if (params == null) {
22954      params = [];
22955    }
22956
22957    // If there are no arguments to the event, use a temporary object
22958    if (params.length === 0) {
22959      params.push({});
22960    }
22961
22962    // Set the `_type` of the first object to the event
22963    params[0]._type = event;
22964
22965    if (event in this.listeners) {
22966      this.invoke(this.listeners[event], slice.call(arguments, 1));
22967    }
22968
22969    if ('*' in this.listeners) {
22970      this.invoke(this.listeners['*'], arguments);
22971    }
22972  };
22973
22974  Observable.prototype.invoke = function (listeners, params) {
22975    for (var i = 0, len = listeners.length; i < len; i++) {
22976      listeners[i].apply(this, params);
22977    }
22978  };
22979
22980  Utils.Observable = Observable;
22981
22982  Utils.generateChars = function (length) {
22983    var chars = '';
22984
22985    for (var i = 0; i < length; i++) {
22986      var randomChar = Math.floor(Math.random() * 36);
22987      chars += randomChar.toString(36);
22988    }
22989
22990    return chars;
22991  };
22992
22993  Utils.bind = function (func, context) {
22994    return function () {
22995      func.apply(context, arguments);
22996    };
22997  };
22998
22999  Utils._convertData = function (data) {
23000    for (var originalKey in data) {
23001      var keys = originalKey.split('-');
23002
23003      var dataLevel = data;
23004
23005      if (keys.length === 1) {
23006        continue;
23007      }
23008
23009      for (var k = 0; k < keys.length; k++) {
23010        var key = keys[k];
23011
23012        // Lowercase the first letter
23013        // By default, dash-separated becomes camelCase
23014        key = key.substring(0, 1).toLowerCase() + key.substring(1);
23015
23016        if (!(key in dataLevel)) {
23017          dataLevel[key] = {};
23018        }
23019
23020        if (k == keys.length - 1) {
23021          dataLevel[key] = data[originalKey];
23022        }
23023
23024        dataLevel = dataLevel[key];
23025      }
23026
23027      delete data[originalKey];
23028    }
23029
23030    return data;
23031  };
23032
23033  Utils.hasScroll = function (index, el) {
23034    // Adapted from the function created by @ShadowScripter
23035    // and adapted by @BillBarry on the Stack Exchange Code Review website.
23036    // The original code can be found at
23037    // http://codereview.stackexchange.com/q/13338
23038    // and was designed to be used with the Sizzle selector engine.
23039
23040    var $el = $(el);
23041    var overflowX = el.style.overflowX;
23042    var overflowY = el.style.overflowY;
23043
23044    //Check both x and y declarations
23045    if (overflowX === overflowY &&
23046        (overflowY === 'hidden' || overflowY === 'visible')) {
23047      return false;
23048    }
23049
23050    if (overflowX === 'scroll' || overflowY === 'scroll') {
23051      return true;
23052    }
23053
23054    return ($el.innerHeight() < el.scrollHeight ||
23055      $el.innerWidth() < el.scrollWidth);
23056  };
23057
23058  Utils.escapeMarkup = function (markup) {
23059    var replaceMap = {
23060      '\\': '&#92;',
23061      '&': '&amp;',
23062      '<': '&lt;',
23063      '>': '&gt;',
23064      '"': '&quot;',
23065      '\'': '&#39;',
23066      '/': '&#47;'
23067    };
23068
23069    // Do not try to escape the markup if it's not a string
23070    if (typeof markup !== 'string') {
23071      return markup;
23072    }
23073
23074    return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
23075      return replaceMap[match];
23076    });
23077  };
23078
23079  // Cache objects in Utils.__cache instead of $.data (see #4346)
23080  Utils.__cache = {};
23081
23082  var id = 0;
23083  Utils.GetUniqueElementId = function (element) {
23084    // Get a unique element Id. If element has no id,
23085    // creates a new unique number, stores it in the id
23086    // attribute and returns the new id with a prefix.
23087    // If an id already exists, it simply returns it with a prefix.
23088
23089    var select2Id = element.getAttribute('data-select2-id');
23090
23091    if (select2Id != null) {
23092      return select2Id;
23093    }
23094
23095    // If element has id, use it.
23096    if (element.id) {
23097      select2Id = 'select2-data-' + element.id;
23098    } else {
23099      select2Id = 'select2-data-' + (++id).toString() +
23100        '-' + Utils.generateChars(4);
23101    }
23102
23103    element.setAttribute('data-select2-id', select2Id);
23104
23105    return select2Id;
23106  };
23107
23108  Utils.StoreData = function (element, name, value) {
23109    // Stores an item in the cache for a specified element.
23110    // name is the cache key.
23111    var id = Utils.GetUniqueElementId(element);
23112    if (!Utils.__cache[id]) {
23113      Utils.__cache[id] = {};
23114    }
23115
23116    Utils.__cache[id][name] = value;
23117  };
23118
23119  Utils.GetData = function (element, name) {
23120    // Retrieves a value from the cache by its key (name)
23121    // name is optional. If no name specified, return
23122    // all cache items for the specified element.
23123    // and for a specified element.
23124    var id = Utils.GetUniqueElementId(element);
23125    if (name) {
23126      if (Utils.__cache[id]) {
23127        if (Utils.__cache[id][name] != null) {
23128          return Utils.__cache[id][name];
23129        }
23130        return $(element).data(name); // Fallback to HTML5 data attribs.
23131      }
23132      return $(element).data(name); // Fallback to HTML5 data attribs.
23133    } else {
23134      return Utils.__cache[id];
23135    }
23136  };
23137
23138  Utils.RemoveData = function (element) {
23139    // Removes all cached items for a specified element.
23140    var id = Utils.GetUniqueElementId(element);
23141    if (Utils.__cache[id] != null) {
23142      delete Utils.__cache[id];
23143    }
23144
23145    element.removeAttribute('data-select2-id');
23146  };
23147
23148  Utils.copyNonInternalCssClasses = function (dest, src) {
23149    var classes;
23150
23151    var destinationClasses = dest.getAttribute('class').trim().split(/\s+/);
23152
23153    destinationClasses = destinationClasses.filter(function (clazz) {
23154      // Save all Select2 classes
23155      return clazz.indexOf('select2-') === 0;
23156    });
23157
23158    var sourceClasses = src.getAttribute('class').trim().split(/\s+/);
23159
23160    sourceClasses = sourceClasses.filter(function (clazz) {
23161      // Only copy non-Select2 classes
23162      return clazz.indexOf('select2-') !== 0;
23163    });
23164
23165    var replacements = destinationClasses.concat(sourceClasses);
23166
23167    dest.setAttribute('class', replacements.join(' '));
23168  };
23169
23170  return Utils;
23171});
23172
23173S2.define('select2/results',[
23174  'jquery',
23175  './utils'
23176], function ($, Utils) {
23177  function Results ($element, options, dataAdapter) {
23178    this.$element = $element;
23179    this.data = dataAdapter;
23180    this.options = options;
23181
23182    Results.__super__.constructor.call(this);
23183  }
23184
23185  Utils.Extend(Results, Utils.Observable);
23186
23187  Results.prototype.render = function () {
23188    var $results = $(
23189      '<ul class="select2-results__options" role="listbox"></ul>'
23190    );
23191
23192    if (this.options.get('multiple')) {
23193      $results.attr('aria-multiselectable', 'true');
23194    }
23195
23196    this.$results = $results;
23197
23198    return $results;
23199  };
23200
23201  Results.prototype.clear = function () {
23202    this.$results.empty();
23203  };
23204
23205  Results.prototype.displayMessage = function (params) {
23206    var escapeMarkup = this.options.get('escapeMarkup');
23207
23208    this.clear();
23209    this.hideLoading();
23210
23211    var $message = $(
23212      '<li role="alert" aria-live="assertive"' +
23213      ' class="select2-results__option"></li>'
23214    );
23215
23216    var message = this.options.get('translations').get(params.message);
23217
23218    $message.append(
23219      escapeMarkup(
23220        message(params.args)
23221      )
23222    );
23223
23224    $message[0].className += ' select2-results__message';
23225
23226    this.$results.append($message);
23227  };
23228
23229  Results.prototype.hideMessages = function () {
23230    this.$results.find('.select2-results__message').remove();
23231  };
23232
23233  Results.prototype.append = function (data) {
23234    this.hideLoading();
23235
23236    var $options = [];
23237
23238    if (data.results == null || data.results.length === 0) {
23239      if (this.$results.children().length === 0) {
23240        this.trigger('results:message', {
23241          message: 'noResults'
23242        });
23243      }
23244
23245      return;
23246    }
23247
23248    data.results = this.sort(data.results);
23249
23250    for (var d = 0; d < data.results.length; d++) {
23251      var item = data.results[d];
23252
23253      var $option = this.option(item);
23254
23255      $options.push($option);
23256    }
23257
23258    this.$results.append($options);
23259  };
23260
23261  Results.prototype.position = function ($results, $dropdown) {
23262    var $resultsContainer = $dropdown.find('.select2-results');
23263    $resultsContainer.append($results);
23264  };
23265
23266  Results.prototype.sort = function (data) {
23267    var sorter = this.options.get('sorter');
23268
23269    return sorter(data);
23270  };
23271
23272  Results.prototype.highlightFirstItem = function () {
23273    var $options = this.$results
23274      .find('.select2-results__option--selectable');
23275
23276    var $selected = $options.filter('.select2-results__option--selected');
23277
23278    // Check if there are any selected options
23279    if ($selected.length > 0) {
23280      // If there are selected options, highlight the first
23281      $selected.first().trigger('mouseenter');
23282    } else {
23283      // If there are no selected options, highlight the first option
23284      // in the dropdown
23285      $options.first().trigger('mouseenter');
23286    }
23287
23288    this.ensureHighlightVisible();
23289  };
23290
23291  Results.prototype.setClasses = function () {
23292    var self = this;
23293
23294    this.data.current(function (selected) {
23295      var selectedIds = selected.map(function (s) {
23296        return s.id.toString();
23297      });
23298
23299      var $options = self.$results
23300        .find('.select2-results__option--selectable');
23301
23302      $options.each(function () {
23303        var $option = $(this);
23304
23305        var item = Utils.GetData(this, 'data');
23306
23307        // id needs to be converted to a string when comparing
23308        var id = '' + item.id;
23309
23310        if ((item.element != null && item.element.selected) ||
23311            (item.element == null && selectedIds.indexOf(id) > -1)) {
23312          this.classList.add('select2-results__option--selected');
23313          $option.attr('aria-selected', 'true');
23314        } else {
23315          this.classList.remove('select2-results__option--selected');
23316          $option.attr('aria-selected', 'false');
23317        }
23318      });
23319
23320    });
23321  };
23322
23323  Results.prototype.showLoading = function (params) {
23324    this.hideLoading();
23325
23326    var loadingMore = this.options.get('translations').get('searching');
23327
23328    var loading = {
23329      disabled: true,
23330      loading: true,
23331      text: loadingMore(params)
23332    };
23333    var $loading = this.option(loading);
23334    $loading.className += ' loading-results';
23335
23336    this.$results.prepend($loading);
23337  };
23338
23339  Results.prototype.hideLoading = function () {
23340    this.$results.find('.loading-results').remove();
23341  };
23342
23343  Results.prototype.option = function (data) {
23344    var option = document.createElement('li');
23345    option.classList.add('select2-results__option');
23346    option.classList.add('select2-results__option--selectable');
23347
23348    var attrs = {
23349      'role': 'option'
23350    };
23351
23352    var matches = window.Element.prototype.matches ||
23353      window.Element.prototype.msMatchesSelector ||
23354      window.Element.prototype.webkitMatchesSelector;
23355
23356    if ((data.element != null && matches.call(data.element, ':disabled')) ||
23357        (data.element == null && data.disabled)) {
23358      attrs['aria-disabled'] = 'true';
23359
23360      option.classList.remove('select2-results__option--selectable');
23361      option.classList.add('select2-results__option--disabled');
23362    }
23363
23364    if (data.id == null) {
23365      option.classList.remove('select2-results__option--selectable');
23366    }
23367
23368    if (data._resultId != null) {
23369      option.id = data._resultId;
23370    }
23371
23372    if (data.title) {
23373      option.title = data.title;
23374    }
23375
23376    if (data.children) {
23377      attrs.role = 'group';
23378      attrs['aria-label'] = data.text;
23379
23380      option.classList.remove('select2-results__option--selectable');
23381      option.classList.add('select2-results__option--group');
23382    }
23383
23384    for (var attr in attrs) {
23385      var val = attrs[attr];
23386
23387      option.setAttribute(attr, val);
23388    }
23389
23390    if (data.children) {
23391      var $option = $(option);
23392
23393      var label = document.createElement('strong');
23394      label.className = 'select2-results__group';
23395
23396      this.template(data, label);
23397
23398      var $children = [];
23399
23400      for (var c = 0; c < data.children.length; c++) {
23401        var child = data.children[c];
23402
23403        var $child = this.option(child);
23404
23405        $children.push($child);
23406      }
23407
23408      var $childrenContainer = $('<ul></ul>', {
23409        'class': 'select2-results__options select2-results__options--nested',
23410        'role': 'none'
23411      });
23412
23413      $childrenContainer.append($children);
23414
23415      $option.append(label);
23416      $option.append($childrenContainer);
23417    } else {
23418      this.template(data, option);
23419    }
23420
23421    Utils.StoreData(option, 'data', data);
23422
23423    return option;
23424  };
23425
23426  Results.prototype.bind = function (container, $container) {
23427    var self = this;
23428
23429    var id = container.id + '-results';
23430
23431    this.$results.attr('id', id);
23432
23433    container.on('results:all', function (params) {
23434      self.clear();
23435      self.append(params.data);
23436
23437      if (container.isOpen()) {
23438        self.setClasses();
23439        self.highlightFirstItem();
23440      }
23441    });
23442
23443    container.on('results:append', function (params) {
23444      self.append(params.data);
23445
23446      if (container.isOpen()) {
23447        self.setClasses();
23448      }
23449    });
23450
23451    container.on('query', function (params) {
23452      self.hideMessages();
23453      self.showLoading(params);
23454    });
23455
23456    container.on('select', function () {
23457      if (!container.isOpen()) {
23458        return;
23459      }
23460
23461      self.setClasses();
23462
23463      if (self.options.get('scrollAfterSelect')) {
23464        self.highlightFirstItem();
23465      }
23466    });
23467
23468    container.on('unselect', function () {
23469      if (!container.isOpen()) {
23470        return;
23471      }
23472
23473      self.setClasses();
23474
23475      if (self.options.get('scrollAfterSelect')) {
23476        self.highlightFirstItem();
23477      }
23478    });
23479
23480    container.on('open', function () {
23481      // When the dropdown is open, aria-expended="true"
23482      self.$results.attr('aria-expanded', 'true');
23483      self.$results.attr('aria-hidden', 'false');
23484
23485      self.setClasses();
23486      self.ensureHighlightVisible();
23487    });
23488
23489    container.on('close', function () {
23490      // When the dropdown is closed, aria-expended="false"
23491      self.$results.attr('aria-expanded', 'false');
23492      self.$results.attr('aria-hidden', 'true');
23493      self.$results.removeAttr('aria-activedescendant');
23494    });
23495
23496    container.on('results:toggle', function () {
23497      var $highlighted = self.getHighlightedResults();
23498
23499      if ($highlighted.length === 0) {
23500        return;
23501      }
23502
23503      $highlighted.trigger('mouseup');
23504    });
23505
23506    container.on('results:select', function () {
23507      var $highlighted = self.getHighlightedResults();
23508
23509      if ($highlighted.length === 0) {
23510        return;
23511      }
23512
23513      var data = Utils.GetData($highlighted[0], 'data');
23514
23515      if ($highlighted.hasClass('select2-results__option--selected')) {
23516        self.trigger('close', {});
23517      } else {
23518        self.trigger('select', {
23519          data: data
23520        });
23521      }
23522    });
23523
23524    container.on('results:previous', function () {
23525      var $highlighted = self.getHighlightedResults();
23526
23527      var $options = self.$results.find('.select2-results__option--selectable');
23528
23529      var currentIndex = $options.index($highlighted);
23530
23531      // If we are already at the top, don't move further
23532      // If no options, currentIndex will be -1
23533      if (currentIndex <= 0) {
23534        return;
23535      }
23536
23537      var nextIndex = currentIndex - 1;
23538
23539      // If none are highlighted, highlight the first
23540      if ($highlighted.length === 0) {
23541        nextIndex = 0;
23542      }
23543
23544      var $next = $options.eq(nextIndex);
23545
23546      $next.trigger('mouseenter');
23547
23548      var currentOffset = self.$results.offset().top;
23549      var nextTop = $next.offset().top;
23550      var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
23551
23552      if (nextIndex === 0) {
23553        self.$results.scrollTop(0);
23554      } else if (nextTop - currentOffset < 0) {
23555        self.$results.scrollTop(nextOffset);
23556      }
23557    });
23558
23559    container.on('results:next', function () {
23560      var $highlighted = self.getHighlightedResults();
23561
23562      var $options = self.$results.find('.select2-results__option--selectable');
23563
23564      var currentIndex = $options.index($highlighted);
23565
23566      var nextIndex = currentIndex + 1;
23567
23568      // If we are at the last option, stay there
23569      if (nextIndex >= $options.length) {
23570        return;
23571      }
23572
23573      var $next = $options.eq(nextIndex);
23574
23575      $next.trigger('mouseenter');
23576
23577      var currentOffset = self.$results.offset().top +
23578        self.$results.outerHeight(false);
23579      var nextBottom = $next.offset().top + $next.outerHeight(false);
23580      var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
23581
23582      if (nextIndex === 0) {
23583        self.$results.scrollTop(0);
23584      } else if (nextBottom > currentOffset) {
23585        self.$results.scrollTop(nextOffset);
23586      }
23587    });
23588
23589    container.on('results:focus', function (params) {
23590      params.element[0].classList.add('select2-results__option--highlighted');
23591      params.element[0].setAttribute('aria-selected', 'true');
23592    });
23593
23594    container.on('results:message', function (params) {
23595      self.displayMessage(params);
23596    });
23597
23598    if ($.fn.mousewheel) {
23599      this.$results.on('mousewheel', function (e) {
23600        var top = self.$results.scrollTop();
23601
23602        var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
23603
23604        var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
23605        var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
23606
23607        if (isAtTop) {
23608          self.$results.scrollTop(0);
23609
23610          e.preventDefault();
23611          e.stopPropagation();
23612        } else if (isAtBottom) {
23613          self.$results.scrollTop(
23614            self.$results.get(0).scrollHeight - self.$results.height()
23615          );
23616
23617          e.preventDefault();
23618          e.stopPropagation();
23619        }
23620      });
23621    }
23622
23623    this.$results.on('mouseup', '.select2-results__option--selectable',
23624      function (evt) {
23625      var $this = $(this);
23626
23627      var data = Utils.GetData(this, 'data');
23628
23629      if ($this.hasClass('select2-results__option--selected')) {
23630        if (self.options.get('multiple')) {
23631          self.trigger('unselect', {
23632            originalEvent: evt,
23633            data: data
23634          });
23635        } else {
23636          self.trigger('close', {});
23637        }
23638
23639        return;
23640      }
23641
23642      self.trigger('select', {
23643        originalEvent: evt,
23644        data: data
23645      });
23646    });
23647
23648    this.$results.on('mouseenter', '.select2-results__option--selectable',
23649      function (evt) {
23650      var data = Utils.GetData(this, 'data');
23651
23652      self.getHighlightedResults()
23653          .removeClass('select2-results__option--highlighted')
23654          .attr('aria-selected', 'false');
23655
23656      self.trigger('results:focus', {
23657        data: data,
23658        element: $(this)
23659      });
23660    });
23661  };
23662
23663  Results.prototype.getHighlightedResults = function () {
23664    var $highlighted = this.$results
23665    .find('.select2-results__option--highlighted');
23666
23667    return $highlighted;
23668  };
23669
23670  Results.prototype.destroy = function () {
23671    this.$results.remove();
23672  };
23673
23674  Results.prototype.ensureHighlightVisible = function () {
23675    var $highlighted = this.getHighlightedResults();
23676
23677    if ($highlighted.length === 0) {
23678      return;
23679    }
23680
23681    var $options = this.$results.find('.select2-results__option--selectable');
23682
23683    var currentIndex = $options.index($highlighted);
23684
23685    var currentOffset = this.$results.offset().top;
23686    var nextTop = $highlighted.offset().top;
23687    var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
23688
23689    var offsetDelta = nextTop - currentOffset;
23690    nextOffset -= $highlighted.outerHeight(false) * 2;
23691
23692    if (currentIndex <= 2) {
23693      this.$results.scrollTop(0);
23694    } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
23695      this.$results.scrollTop(nextOffset);
23696    }
23697  };
23698
23699  Results.prototype.template = function (result, container) {
23700    var template = this.options.get('templateResult');
23701    var escapeMarkup = this.options.get('escapeMarkup');
23702
23703    var content = template(result, container);
23704
23705    if (content == null) {
23706      container.style.display = 'none';
23707    } else if (typeof content === 'string') {
23708      container.innerHTML = escapeMarkup(content);
23709    } else {
23710      $(container).append(content);
23711    }
23712  };
23713
23714  return Results;
23715});
23716
23717S2.define('select2/keys',[
23718
23719], function () {
23720  var KEYS = {
23721    BACKSPACE: 8,
23722    TAB: 9,
23723    ENTER: 13,
23724    SHIFT: 16,
23725    CTRL: 17,
23726    ALT: 18,
23727    ESC: 27,
23728    SPACE: 32,
23729    PAGE_UP: 33,
23730    PAGE_DOWN: 34,
23731    END: 35,
23732    HOME: 36,
23733    LEFT: 37,
23734    UP: 38,
23735    RIGHT: 39,
23736    DOWN: 40,
23737    DELETE: 46
23738  };
23739
23740  return KEYS;
23741});
23742
23743S2.define('select2/selection/base',[
23744  'jquery',
23745  '../utils',
23746  '../keys'
23747], function ($, Utils, KEYS) {
23748  function BaseSelection ($element, options) {
23749    this.$element = $element;
23750    this.options = options;
23751
23752    BaseSelection.__super__.constructor.call(this);
23753  }
23754
23755  Utils.Extend(BaseSelection, Utils.Observable);
23756
23757  BaseSelection.prototype.render = function () {
23758    var $selection = $(
23759      '<span class="select2-selection" role="combobox" ' +
23760      ' aria-haspopup="true" aria-expanded="false">' +
23761      '</span>'
23762    );
23763
23764    this._tabindex = 0;
23765
23766    if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
23767      this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
23768    } else if (this.$element.attr('tabindex') != null) {
23769      this._tabindex = this.$element.attr('tabindex');
23770    }
23771
23772    $selection.attr('title', this.$element.attr('title'));
23773    $selection.attr('tabindex', this._tabindex);
23774    $selection.attr('aria-disabled', 'false');
23775
23776    this.$selection = $selection;
23777
23778    return $selection;
23779  };
23780
23781  BaseSelection.prototype.bind = function (container, $container) {
23782    var self = this;
23783
23784    var resultsId = container.id + '-results';
23785
23786    this.container = container;
23787
23788    this.$selection.on('focus', function (evt) {
23789      self.trigger('focus', evt);
23790    });
23791
23792    this.$selection.on('blur', function (evt) {
23793      self._handleBlur(evt);
23794    });
23795
23796    this.$selection.on('keydown', function (evt) {
23797      self.trigger('keypress', evt);
23798
23799      if (evt.which === KEYS.SPACE) {
23800        evt.preventDefault();
23801      }
23802    });
23803
23804    container.on('results:focus', function (params) {
23805      self.$selection.attr('aria-activedescendant', params.data._resultId);
23806    });
23807
23808    container.on('selection:update', function (params) {
23809      self.update(params.data);
23810    });
23811
23812    container.on('open', function () {
23813      // When the dropdown is open, aria-expanded="true"
23814      self.$selection.attr('aria-expanded', 'true');
23815      self.$selection.attr('aria-owns', resultsId);
23816
23817      self._attachCloseHandler(container);
23818    });
23819
23820    container.on('close', function () {
23821      // When the dropdown is closed, aria-expanded="false"
23822      self.$selection.attr('aria-expanded', 'false');
23823      self.$selection.removeAttr('aria-activedescendant');
23824      self.$selection.removeAttr('aria-owns');
23825
23826      self.$selection.trigger('focus');
23827
23828      self._detachCloseHandler(container);
23829    });
23830
23831    container.on('enable', function () {
23832      self.$selection.attr('tabindex', self._tabindex);
23833      self.$selection.attr('aria-disabled', 'false');
23834    });
23835
23836    container.on('disable', function () {
23837      self.$selection.attr('tabindex', '-1');
23838      self.$selection.attr('aria-disabled', 'true');
23839    });
23840  };
23841
23842  BaseSelection.prototype._handleBlur = function (evt) {
23843    var self = this;
23844
23845    // This needs to be delayed as the active element is the body when the tab
23846    // key is pressed, possibly along with others.
23847    window.setTimeout(function () {
23848      // Don't trigger `blur` if the focus is still in the selection
23849      if (
23850        (document.activeElement == self.$selection[0]) ||
23851        ($.contains(self.$selection[0], document.activeElement))
23852      ) {
23853        return;
23854      }
23855
23856      self.trigger('blur', evt);
23857    }, 1);
23858  };
23859
23860  BaseSelection.prototype._attachCloseHandler = function (container) {
23861
23862    $(document.body).on('mousedown.select2.' + container.id, function (e) {
23863      var $target = $(e.target);
23864
23865      var $select = $target.closest('.select2');
23866
23867      var $all = $('.select2.select2-container--open');
23868
23869      $all.each(function () {
23870        if (this == $select[0]) {
23871          return;
23872        }
23873
23874        var $element = Utils.GetData(this, 'element');
23875
23876        $element.select2('close');
23877      });
23878    });
23879  };
23880
23881  BaseSelection.prototype._detachCloseHandler = function (container) {
23882    $(document.body).off('mousedown.select2.' + container.id);
23883  };
23884
23885  BaseSelection.prototype.position = function ($selection, $container) {
23886    var $selectionContainer = $container.find('.selection');
23887    $selectionContainer.append($selection);
23888  };
23889
23890  BaseSelection.prototype.destroy = function () {
23891    this._detachCloseHandler(this.container);
23892  };
23893
23894  BaseSelection.prototype.update = function (data) {
23895    throw new Error('The `update` method must be defined in child classes.');
23896  };
23897
23898  /**
23899   * Helper method to abstract the "enabled" (not "disabled") state of this
23900   * object.
23901   *
23902   * @return {true} if the instance is not disabled.
23903   * @return {false} if the instance is disabled.
23904   */
23905  BaseSelection.prototype.isEnabled = function () {
23906    return !this.isDisabled();
23907  };
23908
23909  /**
23910   * Helper method to abstract the "disabled" state of this object.
23911   *
23912   * @return {true} if the disabled option is true.
23913   * @return {false} if the disabled option is false.
23914   */
23915  BaseSelection.prototype.isDisabled = function () {
23916    return this.options.get('disabled');
23917  };
23918
23919  return BaseSelection;
23920});
23921
23922S2.define('select2/selection/single',[
23923  'jquery',
23924  './base',
23925  '../utils',
23926  '../keys'
23927], function ($, BaseSelection, Utils, KEYS) {
23928  function SingleSelection () {
23929    SingleSelection.__super__.constructor.apply(this, arguments);
23930  }
23931
23932  Utils.Extend(SingleSelection, BaseSelection);
23933
23934  SingleSelection.prototype.render = function () {
23935    var $selection = SingleSelection.__super__.render.call(this);
23936
23937    $selection[0].classList.add('select2-selection--single');
23938
23939    $selection.html(
23940      '<span class="select2-selection__rendered"></span>' +
23941      '<span class="select2-selection__arrow" role="presentation">' +
23942        '<b role="presentation"></b>' +
23943      '</span>'
23944    );
23945
23946    return $selection;
23947  };
23948
23949  SingleSelection.prototype.bind = function (container, $container) {
23950    var self = this;
23951
23952    SingleSelection.__super__.bind.apply(this, arguments);
23953
23954    var id = container.id + '-container';
23955
23956    this.$selection.find('.select2-selection__rendered')
23957      .attr('id', id)
23958      .attr('role', 'textbox')
23959      .attr('aria-readonly', 'true');
23960    this.$selection.attr('aria-labelledby', id);
23961    this.$selection.attr('aria-controls', id);
23962
23963    this.$selection.on('mousedown', function (evt) {
23964      // Only respond to left clicks
23965      if (evt.which !== 1) {
23966        return;
23967      }
23968
23969      self.trigger('toggle', {
23970        originalEvent: evt
23971      });
23972    });
23973
23974    this.$selection.on('focus', function (evt) {
23975      // User focuses on the container
23976    });
23977
23978    this.$selection.on('blur', function (evt) {
23979      // User exits the container
23980    });
23981
23982    container.on('focus', function (evt) {
23983      if (!container.isOpen()) {
23984        self.$selection.trigger('focus');
23985      }
23986    });
23987  };
23988
23989  SingleSelection.prototype.clear = function () {
23990    var $rendered = this.$selection.find('.select2-selection__rendered');
23991    $rendered.empty();
23992    $rendered.removeAttr('title'); // clear tooltip on empty
23993  };
23994
23995  SingleSelection.prototype.display = function (data, container) {
23996    var template = this.options.get('templateSelection');
23997    var escapeMarkup = this.options.get('escapeMarkup');
23998
23999    return escapeMarkup(template(data, container));
24000  };
24001
24002  SingleSelection.prototype.selectionContainer = function () {
24003    return $('<span></span>');
24004  };
24005
24006  SingleSelection.prototype.update = function (data) {
24007    if (data.length === 0) {
24008      this.clear();
24009      return;
24010    }
24011
24012    var selection = data[0];
24013
24014    var $rendered = this.$selection.find('.select2-selection__rendered');
24015    var formatted = this.display(selection, $rendered);
24016
24017    $rendered.empty().append(formatted);
24018
24019    var title = selection.title || selection.text;
24020
24021    if (title) {
24022      $rendered.attr('title', title);
24023    } else {
24024      $rendered.removeAttr('title');
24025    }
24026  };
24027
24028  return SingleSelection;
24029});
24030
24031S2.define('select2/selection/multiple',[
24032  'jquery',
24033  './base',
24034  '../utils'
24035], function ($, BaseSelection, Utils) {
24036  function MultipleSelection ($element, options) {
24037    MultipleSelection.__super__.constructor.apply(this, arguments);
24038  }
24039
24040  Utils.Extend(MultipleSelection, BaseSelection);
24041
24042  MultipleSelection.prototype.render = function () {
24043    var $selection = MultipleSelection.__super__.render.call(this);
24044
24045    $selection[0].classList.add('select2-selection--multiple');
24046
24047    $selection.html(
24048      '<ul class="select2-selection__rendered"></ul>'
24049    );
24050
24051    return $selection;
24052  };
24053
24054  MultipleSelection.prototype.bind = function (container, $container) {
24055    var self = this;
24056
24057    MultipleSelection.__super__.bind.apply(this, arguments);
24058
24059    var id = container.id + '-container';
24060    this.$selection.find('.select2-selection__rendered').attr('id', id);
24061
24062    this.$selection.on('click', function (evt) {
24063      self.trigger('toggle', {
24064        originalEvent: evt
24065      });
24066    });
24067
24068    this.$selection.on(
24069      'click',
24070      '.select2-selection__choice__remove',
24071      function (evt) {
24072        // Ignore the event if it is disabled
24073        if (self.isDisabled()) {
24074          return;
24075        }
24076
24077        var $remove = $(this);
24078        var $selection = $remove.parent();
24079
24080        var data = Utils.GetData($selection[0], 'data');
24081
24082        self.trigger('unselect', {
24083          originalEvent: evt,
24084          data: data
24085        });
24086      }
24087    );
24088
24089    this.$selection.on(
24090      'keydown',
24091      '.select2-selection__choice__remove',
24092      function (evt) {
24093        // Ignore the event if it is disabled
24094        if (self.isDisabled()) {
24095          return;
24096        }
24097
24098        evt.stopPropagation();
24099      }
24100    );
24101  };
24102
24103  MultipleSelection.prototype.clear = function () {
24104    var $rendered = this.$selection.find('.select2-selection__rendered');
24105    $rendered.empty();
24106    $rendered.removeAttr('title');
24107  };
24108
24109  MultipleSelection.prototype.display = function (data, container) {
24110    var template = this.options.get('templateSelection');
24111    var escapeMarkup = this.options.get('escapeMarkup');
24112
24113    return escapeMarkup(template(data, container));
24114  };
24115
24116  MultipleSelection.prototype.selectionContainer = function () {
24117    var $container = $(
24118      '<li class="select2-selection__choice">' +
24119        '<button type="button" class="select2-selection__choice__remove" ' +
24120        'tabindex="-1">' +
24121          '<span aria-hidden="true">&times;</span>' +
24122        '</button>' +
24123        '<span class="select2-selection__choice__display"></span>' +
24124      '</li>'
24125    );
24126
24127    return $container;
24128  };
24129
24130  MultipleSelection.prototype.update = function (data) {
24131    this.clear();
24132
24133    if (data.length === 0) {
24134      return;
24135    }
24136
24137    var $selections = [];
24138
24139    var selectionIdPrefix = this.$selection.find('.select2-selection__rendered')
24140      .attr('id') + '-choice-';
24141
24142    for (var d = 0; d < data.length; d++) {
24143      var selection = data[d];
24144
24145      var $selection = this.selectionContainer();
24146      var formatted = this.display(selection, $selection);
24147
24148      var selectionId = selectionIdPrefix + Utils.generateChars(4) + '-';
24149
24150      if (selection.id) {
24151        selectionId += selection.id;
24152      } else {
24153        selectionId += Utils.generateChars(4);
24154      }
24155
24156      $selection.find('.select2-selection__choice__display')
24157        .append(formatted)
24158        .attr('id', selectionId);
24159
24160      var title = selection.title || selection.text;
24161
24162      if (title) {
24163        $selection.attr('title', title);
24164      }
24165
24166      var removeItem = this.options.get('translations').get('removeItem');
24167
24168      var $remove = $selection.find('.select2-selection__choice__remove');
24169
24170      $remove.attr('title', removeItem());
24171      $remove.attr('aria-label', removeItem());
24172      $remove.attr('aria-describedby', selectionId);
24173
24174      Utils.StoreData($selection[0], 'data', selection);
24175
24176      $selections.push($selection);
24177    }
24178
24179    var $rendered = this.$selection.find('.select2-selection__rendered');
24180
24181    $rendered.append($selections);
24182  };
24183
24184  return MultipleSelection;
24185});
24186
24187S2.define('select2/selection/placeholder',[
24188
24189], function () {
24190  function Placeholder (decorated, $element, options) {
24191    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
24192
24193    decorated.call(this, $element, options);
24194  }
24195
24196  Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
24197    if (typeof placeholder === 'string') {
24198      placeholder = {
24199        id: '',
24200        text: placeholder
24201      };
24202    }
24203
24204    return placeholder;
24205  };
24206
24207  Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
24208    var $placeholder = this.selectionContainer();
24209
24210    $placeholder.html(this.display(placeholder));
24211    $placeholder[0].classList.add('select2-selection__placeholder');
24212    $placeholder[0].classList.remove('select2-selection__choice');
24213
24214    var placeholderTitle = placeholder.title ||
24215      placeholder.text ||
24216      $placeholder.text();
24217
24218    this.$selection.find('.select2-selection__rendered').attr(
24219      'title',
24220      placeholderTitle
24221    );
24222
24223    return $placeholder;
24224  };
24225
24226  Placeholder.prototype.update = function (decorated, data) {
24227    var singlePlaceholder = (
24228      data.length == 1 && data[0].id != this.placeholder.id
24229    );
24230    var multipleSelections = data.length > 1;
24231
24232    if (multipleSelections || singlePlaceholder) {
24233      return decorated.call(this, data);
24234    }
24235
24236    this.clear();
24237
24238    var $placeholder = this.createPlaceholder(this.placeholder);
24239
24240    this.$selection.find('.select2-selection__rendered').append($placeholder);
24241  };
24242
24243  return Placeholder;
24244});
24245
24246S2.define('select2/selection/allowClear',[
24247  'jquery',
24248  '../keys',
24249  '../utils'
24250], function ($, KEYS, Utils) {
24251  function AllowClear () { }
24252
24253  AllowClear.prototype.bind = function (decorated, container, $container) {
24254    var self = this;
24255
24256    decorated.call(this, container, $container);
24257
24258    if (this.placeholder == null) {
24259      if (this.options.get('debug') && window.console && console.error) {
24260        console.error(
24261          'Select2: The `allowClear` option should be used in combination ' +
24262          'with the `placeholder` option.'
24263        );
24264      }
24265    }
24266
24267    this.$selection.on('mousedown', '.select2-selection__clear',
24268      function (evt) {
24269        self._handleClear(evt);
24270    });
24271
24272    container.on('keypress', function (evt) {
24273      self._handleKeyboardClear(evt, container);
24274    });
24275  };
24276
24277  AllowClear.prototype._handleClear = function (_, evt) {
24278    // Ignore the event if it is disabled
24279    if (this.isDisabled()) {
24280      return;
24281    }
24282
24283    var $clear = this.$selection.find('.select2-selection__clear');
24284
24285    // Ignore the event if nothing has been selected
24286    if ($clear.length === 0) {
24287      return;
24288    }
24289
24290    evt.stopPropagation();
24291
24292    var data = Utils.GetData($clear[0], 'data');
24293
24294    var previousVal = this.$element.val();
24295    this.$element.val(this.placeholder.id);
24296
24297    var unselectData = {
24298      data: data
24299    };
24300    this.trigger('clear', unselectData);
24301    if (unselectData.prevented) {
24302      this.$element.val(previousVal);
24303      return;
24304    }
24305
24306    for (var d = 0; d < data.length; d++) {
24307      unselectData = {
24308        data: data[d]
24309      };
24310
24311      // Trigger the `unselect` event, so people can prevent it from being
24312      // cleared.
24313      this.trigger('unselect', unselectData);
24314
24315      // If the event was prevented, don't clear it out.
24316      if (unselectData.prevented) {
24317        this.$element.val(previousVal);
24318        return;
24319      }
24320    }
24321
24322    this.$element.trigger('input').trigger('change');
24323
24324    this.trigger('toggle', {});
24325  };
24326
24327  AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
24328    if (container.isOpen()) {
24329      return;
24330    }
24331
24332    if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
24333      this._handleClear(evt);
24334    }
24335  };
24336
24337  AllowClear.prototype.update = function (decorated, data) {
24338    decorated.call(this, data);
24339
24340    this.$selection.find('.select2-selection__clear').remove();
24341    this.$selection[0].classList.remove('select2-selection--clearable');
24342
24343    if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
24344        data.length === 0) {
24345      return;
24346    }
24347
24348    var selectionId = this.$selection.find('.select2-selection__rendered')
24349      .attr('id');
24350
24351    var removeAll = this.options.get('translations').get('removeAllItems');
24352
24353    var $remove = $(
24354      '<button type="button" class="select2-selection__clear" tabindex="-1">' +
24355        '<span aria-hidden="true">&times;</span>' +
24356      '</button>'
24357    );
24358    $remove.attr('title', removeAll());
24359    $remove.attr('aria-label', removeAll());
24360    $remove.attr('aria-describedby', selectionId);
24361    Utils.StoreData($remove[0], 'data', data);
24362
24363    this.$selection.prepend($remove);
24364    this.$selection[0].classList.add('select2-selection--clearable');
24365  };
24366
24367  return AllowClear;
24368});
24369
24370S2.define('select2/selection/search',[
24371  'jquery',
24372  '../utils',
24373  '../keys'
24374], function ($, Utils, KEYS) {
24375  function Search (decorated, $element, options) {
24376    decorated.call(this, $element, options);
24377  }
24378
24379  Search.prototype.render = function (decorated) {
24380    var searchLabel = this.options.get('translations').get('search');
24381    var $search = $(
24382      '<span class="select2-search select2-search--inline">' +
24383        '<textarea class="select2-search__field"'+
24384        ' type="search" tabindex="-1"' +
24385        ' autocorrect="off" autocapitalize="none"' +
24386        ' spellcheck="false" role="searchbox" aria-autocomplete="list" >' +
24387        '</textarea>' +
24388      '</span>'
24389    );
24390
24391    this.$searchContainer = $search;
24392    this.$search = $search.find('textarea');
24393
24394    this.$search.prop('autocomplete', this.options.get('autocomplete'));
24395    this.$search.attr('aria-label', searchLabel());
24396
24397    var $rendered = decorated.call(this);
24398
24399    this._transferTabIndex();
24400    $rendered.append(this.$searchContainer);
24401
24402    return $rendered;
24403  };
24404
24405  Search.prototype.bind = function (decorated, container, $container) {
24406    var self = this;
24407
24408    var resultsId = container.id + '-results';
24409    var selectionId = container.id + '-container';
24410
24411    decorated.call(this, container, $container);
24412
24413    self.$search.attr('aria-describedby', selectionId);
24414
24415    container.on('open', function () {
24416      self.$search.attr('aria-controls', resultsId);
24417      self.$search.trigger('focus');
24418    });
24419
24420    container.on('close', function () {
24421      self.$search.val('');
24422      self.resizeSearch();
24423      self.$search.removeAttr('aria-controls');
24424      self.$search.removeAttr('aria-activedescendant');
24425      self.$search.trigger('focus');
24426    });
24427
24428    container.on('enable', function () {
24429      self.$search.prop('disabled', false);
24430
24431      self._transferTabIndex();
24432    });
24433
24434    container.on('disable', function () {
24435      self.$search.prop('disabled', true);
24436    });
24437
24438    container.on('focus', function (evt) {
24439      self.$search.trigger('focus');
24440    });
24441
24442    container.on('results:focus', function (params) {
24443      if (params.data._resultId) {
24444        self.$search.attr('aria-activedescendant', params.data._resultId);
24445      } else {
24446        self.$search.removeAttr('aria-activedescendant');
24447      }
24448    });
24449
24450    this.$selection.on('focusin', '.select2-search--inline', function (evt) {
24451      self.trigger('focus', evt);
24452    });
24453
24454    this.$selection.on('focusout', '.select2-search--inline', function (evt) {
24455      self._handleBlur(evt);
24456    });
24457
24458    this.$selection.on('keydown', '.select2-search--inline', function (evt) {
24459      evt.stopPropagation();
24460
24461      self.trigger('keypress', evt);
24462
24463      self._keyUpPrevented = evt.isDefaultPrevented();
24464
24465      var key = evt.which;
24466
24467      if (key === KEYS.BACKSPACE && self.$search.val() === '') {
24468        var $previousChoice = self.$selection
24469          .find('.select2-selection__choice').last();
24470
24471        if ($previousChoice.length > 0) {
24472          var item = Utils.GetData($previousChoice[0], 'data');
24473
24474          self.searchRemoveChoice(item);
24475
24476          evt.preventDefault();
24477        }
24478      }
24479    });
24480
24481    this.$selection.on('click', '.select2-search--inline', function (evt) {
24482      if (self.$search.val()) {
24483        evt.stopPropagation();
24484      }
24485    });
24486
24487    // Try to detect the IE version should the `documentMode` property that
24488    // is stored on the document. This is only implemented in IE and is
24489    // slightly cleaner than doing a user agent check.
24490    // This property is not available in Edge, but Edge also doesn't have
24491    // this bug.
24492    var msie = document.documentMode;
24493    var disableInputEvents = msie && msie <= 11;
24494
24495    // Workaround for browsers which do not support the `input` event
24496    // This will prevent double-triggering of events for browsers which support
24497    // both the `keyup` and `input` events.
24498    this.$selection.on(
24499      'input.searchcheck',
24500      '.select2-search--inline',
24501      function (evt) {
24502        // IE will trigger the `input` event when a placeholder is used on a
24503        // search box. To get around this issue, we are forced to ignore all
24504        // `input` events in IE and keep using `keyup`.
24505        if (disableInputEvents) {
24506          self.$selection.off('input.search input.searchcheck');
24507          return;
24508        }
24509
24510        // Unbind the duplicated `keyup` event
24511        self.$selection.off('keyup.search');
24512      }
24513    );
24514
24515    this.$selection.on(
24516      'keyup.search input.search',
24517      '.select2-search--inline',
24518      function (evt) {
24519        // IE will trigger the `input` event when a placeholder is used on a
24520        // search box. To get around this issue, we are forced to ignore all
24521        // `input` events in IE and keep using `keyup`.
24522        if (disableInputEvents && evt.type === 'input') {
24523          self.$selection.off('input.search input.searchcheck');
24524          return;
24525        }
24526
24527        var key = evt.which;
24528
24529        // We can freely ignore events from modifier keys
24530        if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
24531          return;
24532        }
24533
24534        // Tabbing will be handled during the `keydown` phase
24535        if (key == KEYS.TAB) {
24536          return;
24537        }
24538
24539        self.handleSearch(evt);
24540      }
24541    );
24542  };
24543
24544  /**
24545   * This method will transfer the tabindex attribute from the rendered
24546   * selection to the search box. This allows for the search box to be used as
24547   * the primary focus instead of the selection container.
24548   *
24549   * @private
24550   */
24551  Search.prototype._transferTabIndex = function (decorated) {
24552    this.$search.attr('tabindex', this.$selection.attr('tabindex'));
24553    this.$selection.attr('tabindex', '-1');
24554  };
24555
24556  Search.prototype.createPlaceholder = function (decorated, placeholder) {
24557    this.$search.attr('placeholder', placeholder.text);
24558  };
24559
24560  Search.prototype.update = function (decorated, data) {
24561    var searchHadFocus = this.$search[0] == document.activeElement;
24562
24563    this.$search.attr('placeholder', '');
24564
24565    decorated.call(this, data);
24566
24567    this.resizeSearch();
24568    if (searchHadFocus) {
24569      this.$search.trigger('focus');
24570    }
24571  };
24572
24573  Search.prototype.handleSearch = function () {
24574    this.resizeSearch();
24575
24576    if (!this._keyUpPrevented) {
24577      var input = this.$search.val();
24578
24579      this.trigger('query', {
24580        term: input
24581      });
24582    }
24583
24584    this._keyUpPrevented = false;
24585  };
24586
24587  Search.prototype.searchRemoveChoice = function (decorated, item) {
24588    this.trigger('unselect', {
24589      data: item
24590    });
24591
24592    this.$search.val(item.text);
24593    this.handleSearch();
24594  };
24595
24596  Search.prototype.resizeSearch = function () {
24597    this.$search.css('width', '25px');
24598
24599    var width = '100%';
24600
24601    if (this.$search.attr('placeholder') === '') {
24602      var minimumWidth = this.$search.val().length + 1;
24603
24604      width = (minimumWidth * 0.75) + 'em';
24605    }
24606
24607    this.$search.css('width', width);
24608  };
24609
24610  return Search;
24611});
24612
24613S2.define('select2/selection/selectionCss',[
24614  '../utils'
24615], function (Utils) {
24616  function SelectionCSS () { }
24617
24618  SelectionCSS.prototype.render = function (decorated) {
24619    var $selection = decorated.call(this);
24620
24621    var selectionCssClass = this.options.get('selectionCssClass') || '';
24622
24623    if (selectionCssClass.indexOf(':all:') !== -1) {
24624      selectionCssClass = selectionCssClass.replace(':all:', '');
24625
24626      Utils.copyNonInternalCssClasses($selection[0], this.$element[0]);
24627    }
24628
24629    $selection.addClass(selectionCssClass);
24630
24631    return $selection;
24632  };
24633
24634  return SelectionCSS;
24635});
24636
24637S2.define('select2/selection/eventRelay',[
24638  'jquery'
24639], function ($) {
24640  function EventRelay () { }
24641
24642  EventRelay.prototype.bind = function (decorated, container, $container) {
24643    var self = this;
24644    var relayEvents = [
24645      'open', 'opening',
24646      'close', 'closing',
24647      'select', 'selecting',
24648      'unselect', 'unselecting',
24649      'clear', 'clearing'
24650    ];
24651
24652    var preventableEvents = [
24653      'opening', 'closing', 'selecting', 'unselecting', 'clearing'
24654    ];
24655
24656    decorated.call(this, container, $container);
24657
24658    container.on('*', function (name, params) {
24659      // Ignore events that should not be relayed
24660      if (relayEvents.indexOf(name) === -1) {
24661        return;
24662      }
24663
24664      // The parameters should always be an object
24665      params = params || {};
24666
24667      // Generate the jQuery event for the Select2 event
24668      var evt = $.Event('select2:' + name, {
24669        params: params
24670      });
24671
24672      self.$element.trigger(evt);
24673
24674      // Only handle preventable events if it was one
24675      if (preventableEvents.indexOf(name) === -1) {
24676        return;
24677      }
24678
24679      params.prevented = evt.isDefaultPrevented();
24680    });
24681  };
24682
24683  return EventRelay;
24684});
24685
24686S2.define('select2/translation',[
24687  'jquery',
24688  'require'
24689], function ($, require) {
24690  function Translation (dict) {
24691    this.dict = dict || {};
24692  }
24693
24694  Translation.prototype.all = function () {
24695    return this.dict;
24696  };
24697
24698  Translation.prototype.get = function (key) {
24699    return this.dict[key];
24700  };
24701
24702  Translation.prototype.extend = function (translation) {
24703    this.dict = $.extend({}, translation.all(), this.dict);
24704  };
24705
24706  // Static functions
24707
24708  Translation._cache = {};
24709
24710  Translation.loadPath = function (path) {
24711    if (!(path in Translation._cache)) {
24712      var translations = require(path);
24713
24714      Translation._cache[path] = translations;
24715    }
24716
24717    return new Translation(Translation._cache[path]);
24718  };
24719
24720  return Translation;
24721});
24722
24723S2.define('select2/diacritics',[
24724
24725], function () {
24726  var diacritics = {
24727    '\u24B6': 'A',
24728    '\uFF21': 'A',
24729    '\u00C0': 'A',
24730    '\u00C1': 'A',
24731    '\u00C2': 'A',
24732    '\u1EA6': 'A',
24733    '\u1EA4': 'A',
24734    '\u1EAA': 'A',
24735    '\u1EA8': 'A',
24736    '\u00C3': 'A',
24737    '\u0100': 'A',
24738    '\u0102': 'A',
24739    '\u1EB0': 'A',
24740    '\u1EAE': 'A',
24741    '\u1EB4': 'A',
24742    '\u1EB2': 'A',
24743    '\u0226': 'A',
24744    '\u01E0': 'A',
24745    '\u00C4': 'A',
24746    '\u01DE': 'A',
24747    '\u1EA2': 'A',
24748    '\u00C5': 'A',
24749    '\u01FA': 'A',
24750    '\u01CD': 'A',
24751    '\u0200': 'A',
24752    '\u0202': 'A',
24753    '\u1EA0': 'A',
24754    '\u1EAC': 'A',
24755    '\u1EB6': 'A',
24756    '\u1E00': 'A',
24757    '\u0104': 'A',
24758    '\u023A': 'A',
24759    '\u2C6F': 'A',
24760    '\uA732': 'AA',
24761    '\u00C6': 'AE',
24762    '\u01FC': 'AE',
24763    '\u01E2': 'AE',
24764    '\uA734': 'AO',
24765    '\uA736': 'AU',
24766    '\uA738': 'AV',
24767    '\uA73A': 'AV',
24768    '\uA73C': 'AY',
24769    '\u24B7': 'B',
24770    '\uFF22': 'B',
24771    '\u1E02': 'B',
24772    '\u1E04': 'B',
24773    '\u1E06': 'B',
24774    '\u0243': 'B',
24775    '\u0182': 'B',
24776    '\u0181': 'B',
24777    '\u24B8': 'C',
24778    '\uFF23': 'C',
24779    '\u0106': 'C',
24780    '\u0108': 'C',
24781    '\u010A': 'C',
24782    '\u010C': 'C',
24783    '\u00C7': 'C',
24784    '\u1E08': 'C',
24785    '\u0187': 'C',
24786    '\u023B': 'C',
24787    '\uA73E': 'C',
24788    '\u24B9': 'D',
24789    '\uFF24': 'D',
24790    '\u1E0A': 'D',
24791    '\u010E': 'D',
24792    '\u1E0C': 'D',
24793    '\u1E10': 'D',
24794    '\u1E12': 'D',
24795    '\u1E0E': 'D',
24796    '\u0110': 'D',
24797    '\u018B': 'D',
24798    '\u018A': 'D',
24799    '\u0189': 'D',
24800    '\uA779': 'D',
24801    '\u01F1': 'DZ',
24802    '\u01C4': 'DZ',
24803    '\u01F2': 'Dz',
24804    '\u01C5': 'Dz',
24805    '\u24BA': 'E',
24806    '\uFF25': 'E',
24807    '\u00C8': 'E',
24808    '\u00C9': 'E',
24809    '\u00CA': 'E',
24810    '\u1EC0': 'E',
24811    '\u1EBE': 'E',
24812    '\u1EC4': 'E',
24813    '\u1EC2': 'E',
24814    '\u1EBC': 'E',
24815    '\u0112': 'E',
24816    '\u1E14': 'E',
24817    '\u1E16': 'E',
24818    '\u0114': 'E',
24819    '\u0116': 'E',
24820    '\u00CB': 'E',
24821    '\u1EBA': 'E',
24822    '\u011A': 'E',
24823    '\u0204': 'E',
24824    '\u0206': 'E',
24825    '\u1EB8': 'E',
24826    '\u1EC6': 'E',
24827    '\u0228': 'E',
24828    '\u1E1C': 'E',
24829    '\u0118': 'E',
24830    '\u1E18': 'E',
24831    '\u1E1A': 'E',
24832    '\u0190': 'E',
24833    '\u018E': 'E',
24834    '\u24BB': 'F',
24835    '\uFF26': 'F',
24836    '\u1E1E': 'F',
24837    '\u0191': 'F',
24838    '\uA77B': 'F',
24839    '\u24BC': 'G',
24840    '\uFF27': 'G',
24841    '\u01F4': 'G',
24842    '\u011C': 'G',
24843    '\u1E20': 'G',
24844    '\u011E': 'G',
24845    '\u0120': 'G',
24846    '\u01E6': 'G',
24847    '\u0122': 'G',
24848    '\u01E4': 'G',
24849    '\u0193': 'G',
24850    '\uA7A0': 'G',
24851    '\uA77D': 'G',
24852    '\uA77E': 'G',
24853    '\u24BD': 'H',
24854    '\uFF28': 'H',
24855    '\u0124': 'H',
24856    '\u1E22': 'H',
24857    '\u1E26': 'H',
24858    '\u021E': 'H',
24859    '\u1E24': 'H',
24860    '\u1E28': 'H',
24861    '\u1E2A': 'H',
24862    '\u0126': 'H',
24863    '\u2C67': 'H',
24864    '\u2C75': 'H',
24865    '\uA78D': 'H',
24866    '\u24BE': 'I',
24867    '\uFF29': 'I',
24868    '\u00CC': 'I',
24869    '\u00CD': 'I',
24870    '\u00CE': 'I',
24871    '\u0128': 'I',
24872    '\u012A': 'I',
24873    '\u012C': 'I',
24874    '\u0130': 'I',
24875    '\u00CF': 'I',
24876    '\u1E2E': 'I',
24877    '\u1EC8': 'I',
24878    '\u01CF': 'I',
24879    '\u0208': 'I',
24880    '\u020A': 'I',
24881    '\u1ECA': 'I',
24882    '\u012E': 'I',
24883    '\u1E2C': 'I',
24884    '\u0197': 'I',
24885    '\u24BF': 'J',
24886    '\uFF2A': 'J',
24887    '\u0134': 'J',
24888    '\u0248': 'J',
24889    '\u24C0': 'K',
24890    '\uFF2B': 'K',
24891    '\u1E30': 'K',
24892    '\u01E8': 'K',
24893    '\u1E32': 'K',
24894    '\u0136': 'K',
24895    '\u1E34': 'K',
24896    '\u0198': 'K',
24897    '\u2C69': 'K',
24898    '\uA740': 'K',
24899    '\uA742': 'K',
24900    '\uA744': 'K',
24901    '\uA7A2': 'K',
24902    '\u24C1': 'L',
24903    '\uFF2C': 'L',
24904    '\u013F': 'L',
24905    '\u0139': 'L',
24906    '\u013D': 'L',
24907    '\u1E36': 'L',
24908    '\u1E38': 'L',
24909    '\u013B': 'L',
24910    '\u1E3C': 'L',
24911    '\u1E3A': 'L',
24912    '\u0141': 'L',
24913    '\u023D': 'L',
24914    '\u2C62': 'L',
24915    '\u2C60': 'L',
24916    '\uA748': 'L',
24917    '\uA746': 'L',
24918    '\uA780': 'L',
24919    '\u01C7': 'LJ',
24920    '\u01C8': 'Lj',
24921    '\u24C2': 'M',
24922    '\uFF2D': 'M',
24923    '\u1E3E': 'M',
24924    '\u1E40': 'M',
24925    '\u1E42': 'M',
24926    '\u2C6E': 'M',
24927    '\u019C': 'M',
24928    '\u24C3': 'N',
24929    '\uFF2E': 'N',
24930    '\u01F8': 'N',
24931    '\u0143': 'N',
24932    '\u00D1': 'N',
24933    '\u1E44': 'N',
24934    '\u0147': 'N',
24935    '\u1E46': 'N',
24936    '\u0145': 'N',
24937    '\u1E4A': 'N',
24938    '\u1E48': 'N',
24939    '\u0220': 'N',
24940    '\u019D': 'N',
24941    '\uA790': 'N',
24942    '\uA7A4': 'N',
24943    '\u01CA': 'NJ',
24944    '\u01CB': 'Nj',
24945    '\u24C4': 'O',
24946    '\uFF2F': 'O',
24947    '\u00D2': 'O',
24948    '\u00D3': 'O',
24949    '\u00D4': 'O',
24950    '\u1ED2': 'O',
24951    '\u1ED0': 'O',
24952    '\u1ED6': 'O',
24953    '\u1ED4': 'O',
24954    '\u00D5': 'O',
24955    '\u1E4C': 'O',
24956    '\u022C': 'O',
24957    '\u1E4E': 'O',
24958    '\u014C': 'O',
24959    '\u1E50': 'O',
24960    '\u1E52': 'O',
24961    '\u014E': 'O',
24962    '\u022E': 'O',
24963    '\u0230': 'O',
24964    '\u00D6': 'O',
24965    '\u022A': 'O',
24966    '\u1ECE': 'O',
24967    '\u0150': 'O',
24968    '\u01D1': 'O',
24969    '\u020C': 'O',
24970    '\u020E': 'O',
24971    '\u01A0': 'O',
24972    '\u1EDC': 'O',
24973    '\u1EDA': 'O',
24974    '\u1EE0': 'O',
24975    '\u1EDE': 'O',
24976    '\u1EE2': 'O',
24977    '\u1ECC': 'O',
24978    '\u1ED8': 'O',
24979    '\u01EA': 'O',
24980    '\u01EC': 'O',
24981    '\u00D8': 'O',
24982    '\u01FE': 'O',
24983    '\u0186': 'O',
24984    '\u019F': 'O',
24985    '\uA74A': 'O',
24986    '\uA74C': 'O',
24987    '\u0152': 'OE',
24988    '\u01A2': 'OI',
24989    '\uA74E': 'OO',
24990    '\u0222': 'OU',
24991    '\u24C5': 'P',
24992    '\uFF30': 'P',
24993    '\u1E54': 'P',
24994    '\u1E56': 'P',
24995    '\u01A4': 'P',
24996    '\u2C63': 'P',
24997    '\uA750': 'P',
24998    '\uA752': 'P',
24999    '\uA754': 'P',
25000    '\u24C6': 'Q',
25001    '\uFF31': 'Q',
25002    '\uA756': 'Q',
25003    '\uA758': 'Q',
25004    '\u024A': 'Q',
25005    '\u24C7': 'R',
25006    '\uFF32': 'R',
25007    '\u0154': 'R',
25008    '\u1E58': 'R',
25009    '\u0158': 'R',
25010    '\u0210': 'R',
25011    '\u0212': 'R',
25012    '\u1E5A': 'R',
25013    '\u1E5C': 'R',
25014    '\u0156': 'R',
25015    '\u1E5E': 'R',
25016    '\u024C': 'R',
25017    '\u2C64': 'R',
25018    '\uA75A': 'R',
25019    '\uA7A6': 'R',
25020    '\uA782': 'R',
25021    '\u24C8': 'S',
25022    '\uFF33': 'S',
25023    '\u1E9E': 'S',
25024    '\u015A': 'S',
25025    '\u1E64': 'S',
25026    '\u015C': 'S',
25027    '\u1E60': 'S',
25028    '\u0160': 'S',
25029    '\u1E66': 'S',
25030    '\u1E62': 'S',
25031    '\u1E68': 'S',
25032    '\u0218': 'S',
25033    '\u015E': 'S',
25034    '\u2C7E': 'S',
25035    '\uA7A8': 'S',
25036    '\uA784': 'S',
25037    '\u24C9': 'T',
25038    '\uFF34': 'T',
25039    '\u1E6A': 'T',
25040    '\u0164': 'T',
25041    '\u1E6C': 'T',
25042    '\u021A': 'T',
25043    '\u0162': 'T',
25044    '\u1E70': 'T',
25045    '\u1E6E': 'T',
25046    '\u0166': 'T',
25047    '\u01AC': 'T',
25048    '\u01AE': 'T',
25049    '\u023E': 'T',
25050    '\uA786': 'T',
25051    '\uA728': 'TZ',
25052    '\u24CA': 'U',
25053    '\uFF35': 'U',
25054    '\u00D9': 'U',
25055    '\u00DA': 'U',
25056    '\u00DB': 'U',
25057    '\u0168': 'U',
25058    '\u1E78': 'U',
25059    '\u016A': 'U',
25060    '\u1E7A': 'U',
25061    '\u016C': 'U',
25062    '\u00DC': 'U',
25063    '\u01DB': 'U',
25064    '\u01D7': 'U',
25065    '\u01D5': 'U',
25066    '\u01D9': 'U',
25067    '\u1EE6': 'U',
25068    '\u016E': 'U',
25069    '\u0170': 'U',
25070    '\u01D3': 'U',
25071    '\u0214': 'U',
25072    '\u0216': 'U',
25073    '\u01AF': 'U',
25074    '\u1EEA': 'U',
25075    '\u1EE8': 'U',
25076    '\u1EEE': 'U',
25077    '\u1EEC': 'U',
25078    '\u1EF0': 'U',
25079    '\u1EE4': 'U',
25080    '\u1E72': 'U',
25081    '\u0172': 'U',
25082    '\u1E76': 'U',
25083    '\u1E74': 'U',
25084    '\u0244': 'U',
25085    '\u24CB': 'V',
25086    '\uFF36': 'V',
25087    '\u1E7C': 'V',
25088    '\u1E7E': 'V',
25089    '\u01B2': 'V',
25090    '\uA75E': 'V',
25091    '\u0245': 'V',
25092    '\uA760': 'VY',
25093    '\u24CC': 'W',
25094    '\uFF37': 'W',
25095    '\u1E80': 'W',
25096    '\u1E82': 'W',
25097    '\u0174': 'W',
25098    '\u1E86': 'W',
25099    '\u1E84': 'W',
25100    '\u1E88': 'W',
25101    '\u2C72': 'W',
25102    '\u24CD': 'X',
25103    '\uFF38': 'X',
25104    '\u1E8A': 'X',
25105    '\u1E8C': 'X',
25106    '\u24CE': 'Y',
25107    '\uFF39': 'Y',
25108    '\u1EF2': 'Y',
25109    '\u00DD': 'Y',
25110    '\u0176': 'Y',
25111    '\u1EF8': 'Y',
25112    '\u0232': 'Y',
25113    '\u1E8E': 'Y',
25114    '\u0178': 'Y',
25115    '\u1EF6': 'Y',
25116    '\u1EF4': 'Y',
25117    '\u01B3': 'Y',
25118    '\u024E': 'Y',
25119    '\u1EFE': 'Y',
25120    '\u24CF': 'Z',
25121    '\uFF3A': 'Z',
25122    '\u0179': 'Z',
25123    '\u1E90': 'Z',
25124    '\u017B': 'Z',
25125    '\u017D': 'Z',
25126    '\u1E92': 'Z',
25127    '\u1E94': 'Z',
25128    '\u01B5': 'Z',
25129    '\u0224': 'Z',
25130    '\u2C7F': 'Z',
25131    '\u2C6B': 'Z',
25132    '\uA762': 'Z',
25133    '\u24D0': 'a',
25134    '\uFF41': 'a',
25135    '\u1E9A': 'a',
25136    '\u00E0': 'a',
25137    '\u00E1': 'a',
25138    '\u00E2': 'a',
25139    '\u1EA7': 'a',
25140    '\u1EA5': 'a',
25141    '\u1EAB': 'a',
25142    '\u1EA9': 'a',
25143    '\u00E3': 'a',
25144    '\u0101': 'a',
25145    '\u0103': 'a',
25146    '\u1EB1': 'a',
25147    '\u1EAF': 'a',
25148    '\u1EB5': 'a',
25149    '\u1EB3': 'a',
25150    '\u0227': 'a',
25151    '\u01E1': 'a',
25152    '\u00E4': 'a',
25153    '\u01DF': 'a',
25154    '\u1EA3': 'a',
25155    '\u00E5': 'a',
25156    '\u01FB': 'a',
25157    '\u01CE': 'a',
25158    '\u0201': 'a',
25159    '\u0203': 'a',
25160    '\u1EA1': 'a',
25161    '\u1EAD': 'a',
25162    '\u1EB7': 'a',
25163    '\u1E01': 'a',
25164    '\u0105': 'a',
25165    '\u2C65': 'a',
25166    '\u0250': 'a',
25167    '\uA733': 'aa',
25168    '\u00E6': 'ae',
25169    '\u01FD': 'ae',
25170    '\u01E3': 'ae',
25171    '\uA735': 'ao',
25172    '\uA737': 'au',
25173    '\uA739': 'av',
25174    '\uA73B': 'av',
25175    '\uA73D': 'ay',
25176    '\u24D1': 'b',
25177    '\uFF42': 'b',
25178    '\u1E03': 'b',
25179    '\u1E05': 'b',
25180    '\u1E07': 'b',
25181    '\u0180': 'b',
25182    '\u0183': 'b',
25183    '\u0253': 'b',
25184    '\u24D2': 'c',
25185    '\uFF43': 'c',
25186    '\u0107': 'c',
25187    '\u0109': 'c',
25188    '\u010B': 'c',
25189    '\u010D': 'c',
25190    '\u00E7': 'c',
25191    '\u1E09': 'c',
25192    '\u0188': 'c',
25193    '\u023C': 'c',
25194    '\uA73F': 'c',
25195    '\u2184': 'c',
25196    '\u24D3': 'd',
25197    '\uFF44': 'd',
25198    '\u1E0B': 'd',
25199    '\u010F': 'd',
25200    '\u1E0D': 'd',
25201    '\u1E11': 'd',
25202    '\u1E13': 'd',
25203    '\u1E0F': 'd',
25204    '\u0111': 'd',
25205    '\u018C': 'd',
25206    '\u0256': 'd',
25207    '\u0257': 'd',
25208    '\uA77A': 'd',
25209    '\u01F3': 'dz',
25210    '\u01C6': 'dz',
25211    '\u24D4': 'e',
25212    '\uFF45': 'e',
25213    '\u00E8': 'e',
25214    '\u00E9': 'e',
25215    '\u00EA': 'e',
25216    '\u1EC1': 'e',
25217    '\u1EBF': 'e',
25218    '\u1EC5': 'e',
25219    '\u1EC3': 'e',
25220    '\u1EBD': 'e',
25221    '\u0113': 'e',
25222    '\u1E15': 'e',
25223    '\u1E17': 'e',
25224    '\u0115': 'e',
25225    '\u0117': 'e',
25226    '\u00EB': 'e',
25227    '\u1EBB': 'e',
25228    '\u011B': 'e',
25229    '\u0205': 'e',
25230    '\u0207': 'e',
25231    '\u1EB9': 'e',
25232    '\u1EC7': 'e',
25233    '\u0229': 'e',
25234    '\u1E1D': 'e',
25235    '\u0119': 'e',
25236    '\u1E19': 'e',
25237    '\u1E1B': 'e',
25238    '\u0247': 'e',
25239    '\u025B': 'e',
25240    '\u01DD': 'e',
25241    '\u24D5': 'f',
25242    '\uFF46': 'f',
25243    '\u1E1F': 'f',
25244    '\u0192': 'f',
25245    '\uA77C': 'f',
25246    '\u24D6': 'g',
25247    '\uFF47': 'g',
25248    '\u01F5': 'g',
25249    '\u011D': 'g',
25250    '\u1E21': 'g',
25251    '\u011F': 'g',
25252    '\u0121': 'g',
25253    '\u01E7': 'g',
25254    '\u0123': 'g',
25255    '\u01E5': 'g',
25256    '\u0260': 'g',
25257    '\uA7A1': 'g',
25258    '\u1D79': 'g',
25259    '\uA77F': 'g',
25260    '\u24D7': 'h',
25261    '\uFF48': 'h',
25262    '\u0125': 'h',
25263    '\u1E23': 'h',
25264    '\u1E27': 'h',
25265    '\u021F': 'h',
25266    '\u1E25': 'h',
25267    '\u1E29': 'h',
25268    '\u1E2B': 'h',
25269    '\u1E96': 'h',
25270    '\u0127': 'h',
25271    '\u2C68': 'h',
25272    '\u2C76': 'h',
25273    '\u0265': 'h',
25274    '\u0195': 'hv',
25275    '\u24D8': 'i',
25276    '\uFF49': 'i',
25277    '\u00EC': 'i',
25278    '\u00ED': 'i',
25279    '\u00EE': 'i',
25280    '\u0129': 'i',
25281    '\u012B': 'i',
25282    '\u012D': 'i',
25283    '\u00EF': 'i',
25284    '\u1E2F': 'i',
25285    '\u1EC9': 'i',
25286    '\u01D0': 'i',
25287    '\u0209': 'i',
25288    '\u020B': 'i',
25289    '\u1ECB': 'i',
25290    '\u012F': 'i',
25291    '\u1E2D': 'i',
25292    '\u0268': 'i',
25293    '\u0131': 'i',
25294    '\u24D9': 'j',
25295    '\uFF4A': 'j',
25296    '\u0135': 'j',
25297    '\u01F0': 'j',
25298    '\u0249': 'j',
25299    '\u24DA': 'k',
25300    '\uFF4B': 'k',
25301    '\u1E31': 'k',
25302    '\u01E9': 'k',
25303    '\u1E33': 'k',
25304    '\u0137': 'k',
25305    '\u1E35': 'k',
25306    '\u0199': 'k',
25307    '\u2C6A': 'k',
25308    '\uA741': 'k',
25309    '\uA743': 'k',
25310    '\uA745': 'k',
25311    '\uA7A3': 'k',
25312    '\u24DB': 'l',
25313    '\uFF4C': 'l',
25314    '\u0140': 'l',
25315    '\u013A': 'l',
25316    '\u013E': 'l',
25317    '\u1E37': 'l',
25318    '\u1E39': 'l',
25319    '\u013C': 'l',
25320    '\u1E3D': 'l',
25321    '\u1E3B': 'l',
25322    '\u017F': 'l',
25323    '\u0142': 'l',
25324    '\u019A': 'l',
25325    '\u026B': 'l',
25326    '\u2C61': 'l',
25327    '\uA749': 'l',
25328    '\uA781': 'l',
25329    '\uA747': 'l',
25330    '\u01C9': 'lj',
25331    '\u24DC': 'm',
25332    '\uFF4D': 'm',
25333    '\u1E3F': 'm',
25334    '\u1E41': 'm',
25335    '\u1E43': 'm',
25336    '\u0271': 'm',
25337    '\u026F': 'm',
25338    '\u24DD': 'n',
25339    '\uFF4E': 'n',
25340    '\u01F9': 'n',
25341    '\u0144': 'n',
25342    '\u00F1': 'n',
25343    '\u1E45': 'n',
25344    '\u0148': 'n',
25345    '\u1E47': 'n',
25346    '\u0146': 'n',
25347    '\u1E4B': 'n',
25348    '\u1E49': 'n',
25349    '\u019E': 'n',
25350    '\u0272': 'n',
25351    '\u0149': 'n',
25352    '\uA791': 'n',
25353    '\uA7A5': 'n',
25354    '\u01CC': 'nj',
25355    '\u24DE': 'o',
25356    '\uFF4F': 'o',
25357    '\u00F2': 'o',
25358    '\u00F3': 'o',
25359    '\u00F4': 'o',
25360    '\u1ED3': 'o',
25361    '\u1ED1': 'o',
25362    '\u1ED7': 'o',
25363    '\u1ED5': 'o',
25364    '\u00F5': 'o',
25365    '\u1E4D': 'o',
25366    '\u022D': 'o',
25367    '\u1E4F': 'o',
25368    '\u014D': 'o',
25369    '\u1E51': 'o',
25370    '\u1E53': 'o',
25371    '\u014F': 'o',
25372    '\u022F': 'o',
25373    '\u0231': 'o',
25374    '\u00F6': 'o',
25375    '\u022B': 'o',
25376    '\u1ECF': 'o',
25377    '\u0151': 'o',
25378    '\u01D2': 'o',
25379    '\u020D': 'o',
25380    '\u020F': 'o',
25381    '\u01A1': 'o',
25382    '\u1EDD': 'o',
25383    '\u1EDB': 'o',
25384    '\u1EE1': 'o',
25385    '\u1EDF': 'o',
25386    '\u1EE3': 'o',
25387    '\u1ECD': 'o',
25388    '\u1ED9': 'o',
25389    '\u01EB': 'o',
25390    '\u01ED': 'o',
25391    '\u00F8': 'o',
25392    '\u01FF': 'o',
25393    '\u0254': 'o',
25394    '\uA74B': 'o',
25395    '\uA74D': 'o',
25396    '\u0275': 'o',
25397    '\u0153': 'oe',
25398    '\u01A3': 'oi',
25399    '\u0223': 'ou',
25400    '\uA74F': 'oo',
25401    '\u24DF': 'p',
25402    '\uFF50': 'p',
25403    '\u1E55': 'p',
25404    '\u1E57': 'p',
25405    '\u01A5': 'p',
25406    '\u1D7D': 'p',
25407    '\uA751': 'p',
25408    '\uA753': 'p',
25409    '\uA755': 'p',
25410    '\u24E0': 'q',
25411    '\uFF51': 'q',
25412    '\u024B': 'q',
25413    '\uA757': 'q',
25414    '\uA759': 'q',
25415    '\u24E1': 'r',
25416    '\uFF52': 'r',
25417    '\u0155': 'r',
25418    '\u1E59': 'r',
25419    '\u0159': 'r',
25420    '\u0211': 'r',
25421    '\u0213': 'r',
25422    '\u1E5B': 'r',
25423    '\u1E5D': 'r',
25424    '\u0157': 'r',
25425    '\u1E5F': 'r',
25426    '\u024D': 'r',
25427    '\u027D': 'r',
25428    '\uA75B': 'r',
25429    '\uA7A7': 'r',
25430    '\uA783': 'r',
25431    '\u24E2': 's',
25432    '\uFF53': 's',
25433    '\u00DF': 's',
25434    '\u015B': 's',
25435    '\u1E65': 's',
25436    '\u015D': 's',
25437    '\u1E61': 's',
25438    '\u0161': 's',
25439    '\u1E67': 's',
25440    '\u1E63': 's',
25441    '\u1E69': 's',
25442    '\u0219': 's',
25443    '\u015F': 's',
25444    '\u023F': 's',
25445    '\uA7A9': 's',
25446    '\uA785': 's',
25447    '\u1E9B': 's',
25448    '\u24E3': 't',
25449    '\uFF54': 't',
25450    '\u1E6B': 't',
25451    '\u1E97': 't',
25452    '\u0165': 't',
25453    '\u1E6D': 't',
25454    '\u021B': 't',
25455    '\u0163': 't',
25456    '\u1E71': 't',
25457    '\u1E6F': 't',
25458    '\u0167': 't',
25459    '\u01AD': 't',
25460    '\u0288': 't',
25461    '\u2C66': 't',
25462    '\uA787': 't',
25463    '\uA729': 'tz',
25464    '\u24E4': 'u',
25465    '\uFF55': 'u',
25466    '\u00F9': 'u',
25467    '\u00FA': 'u',
25468    '\u00FB': 'u',
25469    '\u0169': 'u',
25470    '\u1E79': 'u',
25471    '\u016B': 'u',
25472    '\u1E7B': 'u',
25473    '\u016D': 'u',
25474    '\u00FC': 'u',
25475    '\u01DC': 'u',
25476    '\u01D8': 'u',
25477    '\u01D6': 'u',
25478    '\u01DA': 'u',
25479    '\u1EE7': 'u',
25480    '\u016F': 'u',
25481    '\u0171': 'u',
25482    '\u01D4': 'u',
25483    '\u0215': 'u',
25484    '\u0217': 'u',
25485    '\u01B0': 'u',
25486    '\u1EEB': 'u',
25487    '\u1EE9': 'u',
25488    '\u1EEF': 'u',
25489    '\u1EED': 'u',
25490    '\u1EF1': 'u',
25491    '\u1EE5': 'u',
25492    '\u1E73': 'u',
25493    '\u0173': 'u',
25494    '\u1E77': 'u',
25495    '\u1E75': 'u',
25496    '\u0289': 'u',
25497    '\u24E5': 'v',
25498    '\uFF56': 'v',
25499    '\u1E7D': 'v',
25500    '\u1E7F': 'v',
25501    '\u028B': 'v',
25502    '\uA75F': 'v',
25503    '\u028C': 'v',
25504    '\uA761': 'vy',
25505    '\u24E6': 'w',
25506    '\uFF57': 'w',
25507    '\u1E81': 'w',
25508    '\u1E83': 'w',
25509    '\u0175': 'w',
25510    '\u1E87': 'w',
25511    '\u1E85': 'w',
25512    '\u1E98': 'w',
25513    '\u1E89': 'w',
25514    '\u2C73': 'w',
25515    '\u24E7': 'x',
25516    '\uFF58': 'x',
25517    '\u1E8B': 'x',
25518    '\u1E8D': 'x',
25519    '\u24E8': 'y',
25520    '\uFF59': 'y',
25521    '\u1EF3': 'y',
25522    '\u00FD': 'y',
25523    '\u0177': 'y',
25524    '\u1EF9': 'y',
25525    '\u0233': 'y',
25526    '\u1E8F': 'y',
25527    '\u00FF': 'y',
25528    '\u1EF7': 'y',
25529    '\u1E99': 'y',
25530    '\u1EF5': 'y',
25531    '\u01B4': 'y',
25532    '\u024F': 'y',
25533    '\u1EFF': 'y',
25534    '\u24E9': 'z',
25535    '\uFF5A': 'z',
25536    '\u017A': 'z',
25537    '\u1E91': 'z',
25538    '\u017C': 'z',
25539    '\u017E': 'z',
25540    '\u1E93': 'z',
25541    '\u1E95': 'z',
25542    '\u01B6': 'z',
25543    '\u0225': 'z',
25544    '\u0240': 'z',
25545    '\u2C6C': 'z',
25546    '\uA763': 'z',
25547    '\u0386': '\u0391',
25548    '\u0388': '\u0395',
25549    '\u0389': '\u0397',
25550    '\u038A': '\u0399',
25551    '\u03AA': '\u0399',
25552    '\u038C': '\u039F',
25553    '\u038E': '\u03A5',
25554    '\u03AB': '\u03A5',
25555    '\u038F': '\u03A9',
25556    '\u03AC': '\u03B1',
25557    '\u03AD': '\u03B5',
25558    '\u03AE': '\u03B7',
25559    '\u03AF': '\u03B9',
25560    '\u03CA': '\u03B9',
25561    '\u0390': '\u03B9',
25562    '\u03CC': '\u03BF',
25563    '\u03CD': '\u03C5',
25564    '\u03CB': '\u03C5',
25565    '\u03B0': '\u03C5',
25566    '\u03CE': '\u03C9',
25567    '\u03C2': '\u03C3',
25568    '\u2019': '\''
25569  };
25570
25571  return diacritics;
25572});
25573
25574S2.define('select2/data/base',[
25575  '../utils'
25576], function (Utils) {
25577  function BaseAdapter ($element, options) {
25578    BaseAdapter.__super__.constructor.call(this);
25579  }
25580
25581  Utils.Extend(BaseAdapter, Utils.Observable);
25582
25583  BaseAdapter.prototype.current = function (callback) {
25584    throw new Error('The `current` method must be defined in child classes.');
25585  };
25586
25587  BaseAdapter.prototype.query = function (params, callback) {
25588    throw new Error('The `query` method must be defined in child classes.');
25589  };
25590
25591  BaseAdapter.prototype.bind = function (container, $container) {
25592    // Can be implemented in subclasses
25593  };
25594
25595  BaseAdapter.prototype.destroy = function () {
25596    // Can be implemented in subclasses
25597  };
25598
25599  BaseAdapter.prototype.generateResultId = function (container, data) {
25600    var id = container.id + '-result-';
25601
25602    id += Utils.generateChars(4);
25603
25604    if (data.id != null) {
25605      id += '-' + data.id.toString();
25606    } else {
25607      id += '-' + Utils.generateChars(4);
25608    }
25609    return id;
25610  };
25611
25612  return BaseAdapter;
25613});
25614
25615S2.define('select2/data/select',[
25616  './base',
25617  '../utils',
25618  'jquery'
25619], function (BaseAdapter, Utils, $) {
25620  function SelectAdapter ($element, options) {
25621    this.$element = $element;
25622    this.options = options;
25623
25624    SelectAdapter.__super__.constructor.call(this);
25625  }
25626
25627  Utils.Extend(SelectAdapter, BaseAdapter);
25628
25629  SelectAdapter.prototype.current = function (callback) {
25630    var self = this;
25631
25632    var data = Array.prototype.map.call(
25633      this.$element[0].querySelectorAll(':checked'),
25634      function (selectedElement) {
25635        return self.item($(selectedElement));
25636      }
25637    );
25638
25639    callback(data);
25640  };
25641
25642  SelectAdapter.prototype.select = function (data) {
25643    var self = this;
25644
25645    data.selected = true;
25646
25647    // If data.element is a DOM node, use it instead
25648    if (
25649      data.element != null && data.element.tagName.toLowerCase() === 'option'
25650    ) {
25651      data.element.selected = true;
25652
25653      this.$element.trigger('input').trigger('change');
25654
25655      return;
25656    }
25657
25658    if (this.$element.prop('multiple')) {
25659      this.current(function (currentData) {
25660        var val = [];
25661
25662        data = [data];
25663        data.push.apply(data, currentData);
25664
25665        for (var d = 0; d < data.length; d++) {
25666          var id = data[d].id;
25667
25668          if (val.indexOf(id) === -1) {
25669            val.push(id);
25670          }
25671        }
25672
25673        self.$element.val(val);
25674        self.$element.trigger('input').trigger('change');
25675      });
25676    } else {
25677      var val = data.id;
25678
25679      this.$element.val(val);
25680      this.$element.trigger('input').trigger('change');
25681    }
25682  };
25683
25684  SelectAdapter.prototype.unselect = function (data) {
25685    var self = this;
25686
25687    if (!this.$element.prop('multiple')) {
25688      return;
25689    }
25690
25691    data.selected = false;
25692
25693    if (
25694      data.element != null &&
25695      data.element.tagName.toLowerCase() === 'option'
25696    ) {
25697      data.element.selected = false;
25698
25699      this.$element.trigger('input').trigger('change');
25700
25701      return;
25702    }
25703
25704    this.current(function (currentData) {
25705      var val = [];
25706
25707      for (var d = 0; d < currentData.length; d++) {
25708        var id = currentData[d].id;
25709
25710        if (id !== data.id && val.indexOf(id) === -1) {
25711          val.push(id);
25712        }
25713      }
25714
25715      self.$element.val(val);
25716
25717      self.$element.trigger('input').trigger('change');
25718    });
25719  };
25720
25721  SelectAdapter.prototype.bind = function (container, $container) {
25722    var self = this;
25723
25724    this.container = container;
25725
25726    container.on('select', function (params) {
25727      self.select(params.data);
25728    });
25729
25730    container.on('unselect', function (params) {
25731      self.unselect(params.data);
25732    });
25733  };
25734
25735  SelectAdapter.prototype.destroy = function () {
25736    // Remove anything added to child elements
25737    this.$element.find('*').each(function () {
25738      // Remove any custom data set by Select2
25739      Utils.RemoveData(this);
25740    });
25741  };
25742
25743  SelectAdapter.prototype.query = function (params, callback) {
25744    var data = [];
25745    var self = this;
25746
25747    var $options = this.$element.children();
25748
25749    $options.each(function () {
25750      if (
25751        this.tagName.toLowerCase() !== 'option' &&
25752        this.tagName.toLowerCase() !== 'optgroup'
25753      ) {
25754        return;
25755      }
25756
25757      var $option = $(this);
25758
25759      var option = self.item($option);
25760
25761      var matches = self.matches(params, option);
25762
25763      if (matches !== null) {
25764        data.push(matches);
25765      }
25766    });
25767
25768    callback({
25769      results: data
25770    });
25771  };
25772
25773  SelectAdapter.prototype.addOptions = function ($options) {
25774    this.$element.append($options);
25775  };
25776
25777  SelectAdapter.prototype.option = function (data) {
25778    var option;
25779
25780    if (data.children) {
25781      option = document.createElement('optgroup');
25782      option.label = data.text;
25783    } else {
25784      option = document.createElement('option');
25785
25786      if (option.textContent !== undefined) {
25787        option.textContent = data.text;
25788      } else {
25789        option.innerText = data.text;
25790      }
25791    }
25792
25793    if (data.id !== undefined) {
25794      option.value = data.id;
25795    }
25796
25797    if (data.disabled) {
25798      option.disabled = true;
25799    }
25800
25801    if (data.selected) {
25802      option.selected = true;
25803    }
25804
25805    if (data.title) {
25806      option.title = data.title;
25807    }
25808
25809    var normalizedData = this._normalizeItem(data);
25810    normalizedData.element = option;
25811
25812    // Override the option's data with the combined data
25813    Utils.StoreData(option, 'data', normalizedData);
25814
25815    return $(option);
25816  };
25817
25818  SelectAdapter.prototype.item = function ($option) {
25819    var data = {};
25820
25821    data = Utils.GetData($option[0], 'data');
25822
25823    if (data != null) {
25824      return data;
25825    }
25826
25827    var option = $option[0];
25828
25829    if (option.tagName.toLowerCase() === 'option') {
25830      data = {
25831        id: $option.val(),
25832        text: $option.text(),
25833        disabled: $option.prop('disabled'),
25834        selected: $option.prop('selected'),
25835        title: $option.prop('title')
25836      };
25837    } else if (option.tagName.toLowerCase() === 'optgroup') {
25838      data = {
25839        text: $option.prop('label'),
25840        children: [],
25841        title: $option.prop('title')
25842      };
25843
25844      var $children = $option.children('option');
25845      var children = [];
25846
25847      for (var c = 0; c < $children.length; c++) {
25848        var $child = $($children[c]);
25849
25850        var child = this.item($child);
25851
25852        children.push(child);
25853      }
25854
25855      data.children = children;
25856    }
25857
25858    data = this._normalizeItem(data);
25859    data.element = $option[0];
25860
25861    Utils.StoreData($option[0], 'data', data);
25862
25863    return data;
25864  };
25865
25866  SelectAdapter.prototype._normalizeItem = function (item) {
25867    if (item !== Object(item)) {
25868      item = {
25869        id: item,
25870        text: item
25871      };
25872    }
25873
25874    item = $.extend({}, {
25875      text: ''
25876    }, item);
25877
25878    var defaults = {
25879      selected: false,
25880      disabled: false
25881    };
25882
25883    if (item.id != null) {
25884      item.id = item.id.toString();
25885    }
25886
25887    if (item.text != null) {
25888      item.text = item.text.toString();
25889    }
25890
25891    if (item._resultId == null && item.id && this.container != null) {
25892      item._resultId = this.generateResultId(this.container, item);
25893    }
25894
25895    return $.extend({}, defaults, item);
25896  };
25897
25898  SelectAdapter.prototype.matches = function (params, data) {
25899    var matcher = this.options.get('matcher');
25900
25901    return matcher(params, data);
25902  };
25903
25904  return SelectAdapter;
25905});
25906
25907S2.define('select2/data/array',[
25908  './select',
25909  '../utils',
25910  'jquery'
25911], function (SelectAdapter, Utils, $) {
25912  function ArrayAdapter ($element, options) {
25913    this._dataToConvert = options.get('data') || [];
25914
25915    ArrayAdapter.__super__.constructor.call(this, $element, options);
25916  }
25917
25918  Utils.Extend(ArrayAdapter, SelectAdapter);
25919
25920  ArrayAdapter.prototype.bind = function (container, $container) {
25921    ArrayAdapter.__super__.bind.call(this, container, $container);
25922
25923    this.addOptions(this.convertToOptions(this._dataToConvert));
25924  };
25925
25926  ArrayAdapter.prototype.select = function (data) {
25927    var $option = this.$element.find('option').filter(function (i, elm) {
25928      return elm.value == data.id.toString();
25929    });
25930
25931    if ($option.length === 0) {
25932      $option = this.option(data);
25933
25934      this.addOptions($option);
25935    }
25936
25937    ArrayAdapter.__super__.select.call(this, data);
25938  };
25939
25940  ArrayAdapter.prototype.convertToOptions = function (data) {
25941    var self = this;
25942
25943    var $existing = this.$element.find('option');
25944    var existingIds = $existing.map(function () {
25945      return self.item($(this)).id;
25946    }).get();
25947
25948    var $options = [];
25949
25950    // Filter out all items except for the one passed in the argument
25951    function onlyItem (item) {
25952      return function () {
25953        return $(this).val() == item.id;
25954      };
25955    }
25956
25957    for (var d = 0; d < data.length; d++) {
25958      var item = this._normalizeItem(data[d]);
25959
25960      // Skip items which were pre-loaded, only merge the data
25961      if (existingIds.indexOf(item.id) >= 0) {
25962        var $existingOption = $existing.filter(onlyItem(item));
25963
25964        var existingData = this.item($existingOption);
25965        var newData = $.extend(true, {}, item, existingData);
25966
25967        var $newOption = this.option(newData);
25968
25969        $existingOption.replaceWith($newOption);
25970
25971        continue;
25972      }
25973
25974      var $option = this.option(item);
25975
25976      if (item.children) {
25977        var $children = this.convertToOptions(item.children);
25978
25979        $option.append($children);
25980      }
25981
25982      $options.push($option);
25983    }
25984
25985    return $options;
25986  };
25987
25988  return ArrayAdapter;
25989});
25990
25991S2.define('select2/data/ajax',[
25992  './array',
25993  '../utils',
25994  'jquery'
25995], function (ArrayAdapter, Utils, $) {
25996  function AjaxAdapter ($element, options) {
25997    this.ajaxOptions = this._applyDefaults(options.get('ajax'));
25998
25999    if (this.ajaxOptions.processResults != null) {
26000      this.processResults = this.ajaxOptions.processResults;
26001    }
26002
26003    AjaxAdapter.__super__.constructor.call(this, $element, options);
26004  }
26005
26006  Utils.Extend(AjaxAdapter, ArrayAdapter);
26007
26008  AjaxAdapter.prototype._applyDefaults = function (options) {
26009    var defaults = {
26010      data: function (params) {
26011        return $.extend({}, params, {
26012          q: params.term
26013        });
26014      },
26015      transport: function (params, success, failure) {
26016        var $request = $.ajax(params);
26017
26018        $request.then(success);
26019        $request.fail(failure);
26020
26021        return $request;
26022      }
26023    };
26024
26025    return $.extend({}, defaults, options, true);
26026  };
26027
26028  AjaxAdapter.prototype.processResults = function (results) {
26029    return results;
26030  };
26031
26032  AjaxAdapter.prototype.query = function (params, callback) {
26033    var matches = [];
26034    var self = this;
26035
26036    if (this._request != null) {
26037      // JSONP requests cannot always be aborted
26038      if (typeof this._request.abort === 'function') {
26039        this._request.abort();
26040      }
26041
26042      this._request = null;
26043    }
26044
26045    var options = $.extend({
26046      type: 'GET'
26047    }, this.ajaxOptions);
26048
26049    if (typeof options.url === 'function') {
26050      options.url = options.url.call(this.$element, params);
26051    }
26052
26053    if (typeof options.data === 'function') {
26054      options.data = options.data.call(this.$element, params);
26055    }
26056
26057    function request () {
26058      var $request = options.transport(options, function (data) {
26059        var results = self.processResults(data, params);
26060
26061        if (self.options.get('debug') && window.console && console.error) {
26062          // Check to make sure that the response included a `results` key.
26063          if (!results || !results.results || !Array.isArray(results.results)) {
26064            console.error(
26065              'Select2: The AJAX results did not return an array in the ' +
26066              '`results` key of the response.'
26067            );
26068          }
26069        }
26070
26071        callback(results);
26072      }, function () {
26073        // Attempt to detect if a request was aborted
26074        // Only works if the transport exposes a status property
26075        if ('status' in $request &&
26076            ($request.status === 0 || $request.status === '0')) {
26077          return;
26078        }
26079
26080        self.trigger('results:message', {
26081          message: 'errorLoading'
26082        });
26083      });
26084
26085      self._request = $request;
26086    }
26087
26088    if (this.ajaxOptions.delay && params.term != null) {
26089      if (this._queryTimeout) {
26090        window.clearTimeout(this._queryTimeout);
26091      }
26092
26093      this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
26094    } else {
26095      request();
26096    }
26097  };
26098
26099  return AjaxAdapter;
26100});
26101
26102S2.define('select2/data/tags',[
26103  'jquery'
26104], function ($) {
26105  function Tags (decorated, $element, options) {
26106    var tags = options.get('tags');
26107
26108    var createTag = options.get('createTag');
26109
26110    if (createTag !== undefined) {
26111      this.createTag = createTag;
26112    }
26113
26114    var insertTag = options.get('insertTag');
26115
26116    if (insertTag !== undefined) {
26117        this.insertTag = insertTag;
26118    }
26119
26120    decorated.call(this, $element, options);
26121
26122    if (Array.isArray(tags)) {
26123      for (var t = 0; t < tags.length; t++) {
26124        var tag = tags[t];
26125        var item = this._normalizeItem(tag);
26126
26127        var $option = this.option(item);
26128
26129        this.$element.append($option);
26130      }
26131    }
26132  }
26133
26134  Tags.prototype.query = function (decorated, params, callback) {
26135    var self = this;
26136
26137    this._removeOldTags();
26138
26139    if (params.term == null || params.page != null) {
26140      decorated.call(this, params, callback);
26141      return;
26142    }
26143
26144    function wrapper (obj, child) {
26145      var data = obj.results;
26146
26147      for (var i = 0; i < data.length; i++) {
26148        var option = data[i];
26149
26150        var checkChildren = (
26151          option.children != null &&
26152          !wrapper({
26153            results: option.children
26154          }, true)
26155        );
26156
26157        var optionText = (option.text || '').toUpperCase();
26158        var paramsTerm = (params.term || '').toUpperCase();
26159
26160        var checkText = optionText === paramsTerm;
26161
26162        if (checkText || checkChildren) {
26163          if (child) {
26164            return false;
26165          }
26166
26167          obj.data = data;
26168          callback(obj);
26169
26170          return;
26171        }
26172      }
26173
26174      if (child) {
26175        return true;
26176      }
26177
26178      var tag = self.createTag(params);
26179
26180      if (tag != null) {
26181        var $option = self.option(tag);
26182        $option.attr('data-select2-tag', 'true');
26183
26184        self.addOptions([$option]);
26185
26186        self.insertTag(data, tag);
26187      }
26188
26189      obj.results = data;
26190
26191      callback(obj);
26192    }
26193
26194    decorated.call(this, params, wrapper);
26195  };
26196
26197  Tags.prototype.createTag = function (decorated, params) {
26198    if (params.term == null) {
26199      return null;
26200    }
26201
26202    var term = params.term.trim();
26203
26204    if (term === '') {
26205      return null;
26206    }
26207
26208    return {
26209      id: term,
26210      text: term
26211    };
26212  };
26213
26214  Tags.prototype.insertTag = function (_, data, tag) {
26215    data.unshift(tag);
26216  };
26217
26218  Tags.prototype._removeOldTags = function (_) {
26219    var $options = this.$element.find('option[data-select2-tag]');
26220
26221    $options.each(function () {
26222      if (this.selected) {
26223        return;
26224      }
26225
26226      $(this).remove();
26227    });
26228  };
26229
26230  return Tags;
26231});
26232
26233S2.define('select2/data/tokenizer',[
26234  'jquery'
26235], function ($) {
26236  function Tokenizer (decorated, $element, options) {
26237    var tokenizer = options.get('tokenizer');
26238
26239    if (tokenizer !== undefined) {
26240      this.tokenizer = tokenizer;
26241    }
26242
26243    decorated.call(this, $element, options);
26244  }
26245
26246  Tokenizer.prototype.bind = function (decorated, container, $container) {
26247    decorated.call(this, container, $container);
26248
26249    this.$search =  container.dropdown.$search || container.selection.$search ||
26250      $container.find('.select2-search__field');
26251  };
26252
26253  Tokenizer.prototype.query = function (decorated, params, callback) {
26254    var self = this;
26255
26256    function createAndSelect (data) {
26257      // Normalize the data object so we can use it for checks
26258      var item = self._normalizeItem(data);
26259
26260      // Check if the data object already exists as a tag
26261      // Select it if it doesn't
26262      var $existingOptions = self.$element.find('option').filter(function () {
26263        return $(this).val() === item.id;
26264      });
26265
26266      // If an existing option wasn't found for it, create the option
26267      if (!$existingOptions.length) {
26268        var $option = self.option(item);
26269        $option.attr('data-select2-tag', true);
26270
26271        self._removeOldTags();
26272        self.addOptions([$option]);
26273      }
26274
26275      // Select the item, now that we know there is an option for it
26276      select(item);
26277    }
26278
26279    function select (data) {
26280      self.trigger('select', {
26281        data: data
26282      });
26283    }
26284
26285    params.term = params.term || '';
26286
26287    var tokenData = this.tokenizer(params, this.options, createAndSelect);
26288
26289    if (tokenData.term !== params.term) {
26290      // Replace the search term if we have the search box
26291      if (this.$search.length) {
26292        this.$search.val(tokenData.term);
26293        this.$search.trigger('focus');
26294      }
26295
26296      params.term = tokenData.term;
26297    }
26298
26299    decorated.call(this, params, callback);
26300  };
26301
26302  Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
26303    var separators = options.get('tokenSeparators') || [];
26304    var term = params.term;
26305    var i = 0;
26306
26307    var createTag = this.createTag || function (params) {
26308      return {
26309        id: params.term,
26310        text: params.term
26311      };
26312    };
26313
26314    while (i < term.length) {
26315      var termChar = term[i];
26316
26317      if (separators.indexOf(termChar) === -1) {
26318        i++;
26319
26320        continue;
26321      }
26322
26323      var part = term.substr(0, i);
26324      var partParams = $.extend({}, params, {
26325        term: part
26326      });
26327
26328      var data = createTag(partParams);
26329
26330      if (data == null) {
26331        i++;
26332        continue;
26333      }
26334
26335      callback(data);
26336
26337      // Reset the term to not include the tokenized portion
26338      term = term.substr(i + 1) || '';
26339      i = 0;
26340    }
26341
26342    return {
26343      term: term
26344    };
26345  };
26346
26347  return Tokenizer;
26348});
26349
26350S2.define('select2/data/minimumInputLength',[
26351
26352], function () {
26353  function MinimumInputLength (decorated, $e, options) {
26354    this.minimumInputLength = options.get('minimumInputLength');
26355
26356    decorated.call(this, $e, options);
26357  }
26358
26359  MinimumInputLength.prototype.query = function (decorated, params, callback) {
26360    params.term = params.term || '';
26361
26362    if (params.term.length < this.minimumInputLength) {
26363      this.trigger('results:message', {
26364        message: 'inputTooShort',
26365        args: {
26366          minimum: this.minimumInputLength,
26367          input: params.term,
26368          params: params
26369        }
26370      });
26371
26372      return;
26373    }
26374
26375    decorated.call(this, params, callback);
26376  };
26377
26378  return MinimumInputLength;
26379});
26380
26381S2.define('select2/data/maximumInputLength',[
26382
26383], function () {
26384  function MaximumInputLength (decorated, $e, options) {
26385    this.maximumInputLength = options.get('maximumInputLength');
26386
26387    decorated.call(this, $e, options);
26388  }
26389
26390  MaximumInputLength.prototype.query = function (decorated, params, callback) {
26391    params.term = params.term || '';
26392
26393    if (this.maximumInputLength > 0 &&
26394        params.term.length > this.maximumInputLength) {
26395      this.trigger('results:message', {
26396        message: 'inputTooLong',
26397        args: {
26398          maximum: this.maximumInputLength,
26399          input: params.term,
26400          params: params
26401        }
26402      });
26403
26404      return;
26405    }
26406
26407    decorated.call(this, params, callback);
26408  };
26409
26410  return MaximumInputLength;
26411});
26412
26413S2.define('select2/data/maximumSelectionLength',[
26414
26415], function (){
26416  function MaximumSelectionLength (decorated, $e, options) {
26417    this.maximumSelectionLength = options.get('maximumSelectionLength');
26418
26419    decorated.call(this, $e, options);
26420  }
26421
26422  MaximumSelectionLength.prototype.bind =
26423    function (decorated, container, $container) {
26424      var self = this;
26425
26426      decorated.call(this, container, $container);
26427
26428      container.on('select', function () {
26429        self._checkIfMaximumSelected();
26430      });
26431  };
26432
26433  MaximumSelectionLength.prototype.query =
26434    function (decorated, params, callback) {
26435      var self = this;
26436
26437      this._checkIfMaximumSelected(function () {
26438        decorated.call(self, params, callback);
26439      });
26440  };
26441
26442  MaximumSelectionLength.prototype._checkIfMaximumSelected =
26443    function (_, successCallback) {
26444      var self = this;
26445
26446      this.current(function (currentData) {
26447        var count = currentData != null ? currentData.length : 0;
26448        if (self.maximumSelectionLength > 0 &&
26449          count >= self.maximumSelectionLength) {
26450          self.trigger('results:message', {
26451            message: 'maximumSelected',
26452            args: {
26453              maximum: self.maximumSelectionLength
26454            }
26455          });
26456          return;
26457        }
26458
26459        if (successCallback) {
26460          successCallback();
26461        }
26462      });
26463  };
26464
26465  return MaximumSelectionLength;
26466});
26467
26468S2.define('select2/dropdown',[
26469  'jquery',
26470  './utils'
26471], function ($, Utils) {
26472  function Dropdown ($element, options) {
26473    this.$element = $element;
26474    this.options = options;
26475
26476    Dropdown.__super__.constructor.call(this);
26477  }
26478
26479  Utils.Extend(Dropdown, Utils.Observable);
26480
26481  Dropdown.prototype.render = function () {
26482    var $dropdown = $(
26483      '<span class="select2-dropdown">' +
26484        '<span class="select2-results"></span>' +
26485      '</span>'
26486    );
26487
26488    $dropdown.attr('dir', this.options.get('dir'));
26489
26490    this.$dropdown = $dropdown;
26491
26492    return $dropdown;
26493  };
26494
26495  Dropdown.prototype.bind = function () {
26496    // Should be implemented in subclasses
26497  };
26498
26499  Dropdown.prototype.position = function ($dropdown, $container) {
26500    // Should be implemented in subclasses
26501  };
26502
26503  Dropdown.prototype.destroy = function () {
26504    // Remove the dropdown from the DOM
26505    this.$dropdown.remove();
26506  };
26507
26508  return Dropdown;
26509});
26510
26511S2.define('select2/dropdown/search',[
26512  'jquery'
26513], function ($) {
26514  function Search () { }
26515
26516  Search.prototype.render = function (decorated) {
26517    var $rendered = decorated.call(this);
26518    var searchLabel = this.options.get('translations').get('search');
26519
26520    var $search = $(
26521      '<span class="select2-search select2-search--dropdown">' +
26522        '<input class="select2-search__field" type="search" tabindex="-1"' +
26523        ' autocorrect="off" autocapitalize="none"' +
26524        ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
26525      '</span>'
26526    );
26527
26528    this.$searchContainer = $search;
26529    this.$search = $search.find('input');
26530
26531    this.$search.prop('autocomplete', this.options.get('autocomplete'));
26532    this.$search.attr('aria-label', searchLabel());
26533
26534    $rendered.prepend($search);
26535
26536    return $rendered;
26537  };
26538
26539  Search.prototype.bind = function (decorated, container, $container) {
26540    var self = this;
26541
26542    var resultsId = container.id + '-results';
26543
26544    decorated.call(this, container, $container);
26545
26546    this.$search.on('keydown', function (evt) {
26547      self.trigger('keypress', evt);
26548
26549      self._keyUpPrevented = evt.isDefaultPrevented();
26550    });
26551
26552    // Workaround for browsers which do not support the `input` event
26553    // This will prevent double-triggering of events for browsers which support
26554    // both the `keyup` and `input` events.
26555    this.$search.on('input', function (evt) {
26556      // Unbind the duplicated `keyup` event
26557      $(this).off('keyup');
26558    });
26559
26560    this.$search.on('keyup input', function (evt) {
26561      self.handleSearch(evt);
26562    });
26563
26564    container.on('open', function () {
26565      self.$search.attr('tabindex', 0);
26566      self.$search.attr('aria-controls', resultsId);
26567
26568      self.$search.trigger('focus');
26569
26570      window.setTimeout(function () {
26571        self.$search.trigger('focus');
26572      }, 0);
26573    });
26574
26575    container.on('close', function () {
26576      self.$search.attr('tabindex', -1);
26577      self.$search.removeAttr('aria-controls');
26578      self.$search.removeAttr('aria-activedescendant');
26579
26580      self.$search.val('');
26581      self.$search.trigger('blur');
26582    });
26583
26584    container.on('focus', function () {
26585      if (!container.isOpen()) {
26586        self.$search.trigger('focus');
26587      }
26588    });
26589
26590    container.on('results:all', function (params) {
26591      if (params.query.term == null || params.query.term === '') {
26592        var showSearch = self.showSearch(params);
26593
26594        if (showSearch) {
26595          self.$searchContainer[0].classList.remove('select2-search--hide');
26596        } else {
26597          self.$searchContainer[0].classList.add('select2-search--hide');
26598        }
26599      }
26600    });
26601
26602    container.on('results:focus', function (params) {
26603      if (params.data._resultId) {
26604        self.$search.attr('aria-activedescendant', params.data._resultId);
26605      } else {
26606        self.$search.removeAttr('aria-activedescendant');
26607      }
26608    });
26609  };
26610
26611  Search.prototype.handleSearch = function (evt) {
26612    if (!this._keyUpPrevented) {
26613      var input = this.$search.val();
26614
26615      this.trigger('query', {
26616        term: input
26617      });
26618    }
26619
26620    this._keyUpPrevented = false;
26621  };
26622
26623  Search.prototype.showSearch = function (_, params) {
26624    return true;
26625  };
26626
26627  return Search;
26628});
26629
26630S2.define('select2/dropdown/hidePlaceholder',[
26631
26632], function () {
26633  function HidePlaceholder (decorated, $element, options, dataAdapter) {
26634    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
26635
26636    decorated.call(this, $element, options, dataAdapter);
26637  }
26638
26639  HidePlaceholder.prototype.append = function (decorated, data) {
26640    data.results = this.removePlaceholder(data.results);
26641
26642    decorated.call(this, data);
26643  };
26644
26645  HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
26646    if (typeof placeholder === 'string') {
26647      placeholder = {
26648        id: '',
26649        text: placeholder
26650      };
26651    }
26652
26653    return placeholder;
26654  };
26655
26656  HidePlaceholder.prototype.removePlaceholder = function (_, data) {
26657    var modifiedData = data.slice(0);
26658
26659    for (var d = data.length - 1; d >= 0; d--) {
26660      var item = data[d];
26661
26662      if (this.placeholder.id === item.id) {
26663        modifiedData.splice(d, 1);
26664      }
26665    }
26666
26667    return modifiedData;
26668  };
26669
26670  return HidePlaceholder;
26671});
26672
26673S2.define('select2/dropdown/infiniteScroll',[
26674  'jquery'
26675], function ($) {
26676  function InfiniteScroll (decorated, $element, options, dataAdapter) {
26677    this.lastParams = {};
26678
26679    decorated.call(this, $element, options, dataAdapter);
26680
26681    this.$loadingMore = this.createLoadingMore();
26682    this.loading = false;
26683  }
26684
26685  InfiniteScroll.prototype.append = function (decorated, data) {
26686    this.$loadingMore.remove();
26687    this.loading = false;
26688
26689    decorated.call(this, data);
26690
26691    if (this.showLoadingMore(data)) {
26692      this.$results.append(this.$loadingMore);
26693      this.loadMoreIfNeeded();
26694    }
26695  };
26696
26697  InfiniteScroll.prototype.bind = function (decorated, container, $container) {
26698    var self = this;
26699
26700    decorated.call(this, container, $container);
26701
26702    container.on('query', function (params) {
26703      self.lastParams = params;
26704      self.loading = true;
26705    });
26706
26707    container.on('query:append', function (params) {
26708      self.lastParams = params;
26709      self.loading = true;
26710    });
26711
26712    this.$results.on('scroll', this.loadMoreIfNeeded.bind(this));
26713  };
26714
26715  InfiniteScroll.prototype.loadMoreIfNeeded = function () {
26716    var isLoadMoreVisible = $.contains(
26717      document.documentElement,
26718      this.$loadingMore[0]
26719    );
26720
26721    if (this.loading || !isLoadMoreVisible) {
26722      return;
26723    }
26724
26725    var currentOffset = this.$results.offset().top +
26726      this.$results.outerHeight(false);
26727    var loadingMoreOffset = this.$loadingMore.offset().top +
26728      this.$loadingMore.outerHeight(false);
26729
26730    if (currentOffset + 50 >= loadingMoreOffset) {
26731      this.loadMore();
26732    }
26733  };
26734
26735  InfiniteScroll.prototype.loadMore = function () {
26736    this.loading = true;
26737
26738    var params = $.extend({}, {page: 1}, this.lastParams);
26739
26740    params.page++;
26741
26742    this.trigger('query:append', params);
26743  };
26744
26745  InfiniteScroll.prototype.showLoadingMore = function (_, data) {
26746    return data.pagination && data.pagination.more;
26747  };
26748
26749  InfiniteScroll.prototype.createLoadingMore = function () {
26750    var $option = $(
26751      '<li ' +
26752      'class="select2-results__option select2-results__option--load-more"' +
26753      'role="option" aria-disabled="true"></li>'
26754    );
26755
26756    var message = this.options.get('translations').get('loadingMore');
26757
26758    $option.html(message(this.lastParams));
26759
26760    return $option;
26761  };
26762
26763  return InfiniteScroll;
26764});
26765
26766S2.define('select2/dropdown/attachBody',[
26767  'jquery',
26768  '../utils'
26769], function ($, Utils) {
26770  function AttachBody (decorated, $element, options) {
26771    this.$dropdownParent = $(options.get('dropdownParent') || document.body);
26772
26773    decorated.call(this, $element, options);
26774  }
26775
26776  AttachBody.prototype.bind = function (decorated, container, $container) {
26777    var self = this;
26778
26779    decorated.call(this, container, $container);
26780
26781    container.on('open', function () {
26782      self._showDropdown();
26783      self._attachPositioningHandler(container);
26784
26785      // Must bind after the results handlers to ensure correct sizing
26786      self._bindContainerResultHandlers(container);
26787    });
26788
26789    container.on('close', function () {
26790      self._hideDropdown();
26791      self._detachPositioningHandler(container);
26792    });
26793
26794    this.$dropdownContainer.on('mousedown', function (evt) {
26795      evt.stopPropagation();
26796    });
26797  };
26798
26799  AttachBody.prototype.destroy = function (decorated) {
26800    decorated.call(this);
26801
26802    this.$dropdownContainer.remove();
26803  };
26804
26805  AttachBody.prototype.position = function (decorated, $dropdown, $container) {
26806    // Clone all of the container classes
26807    $dropdown.attr('class', $container.attr('class'));
26808
26809    $dropdown[0].classList.remove('select2');
26810    $dropdown[0].classList.add('select2-container--open');
26811
26812    $dropdown.css({
26813      position: 'absolute',
26814      top: -999999
26815    });
26816
26817    this.$container = $container;
26818  };
26819
26820  AttachBody.prototype.render = function (decorated) {
26821    var $container = $('<span></span>');
26822
26823    var $dropdown = decorated.call(this);
26824    $container.append($dropdown);
26825
26826    this.$dropdownContainer = $container;
26827
26828    return $container;
26829  };
26830
26831  AttachBody.prototype._hideDropdown = function (decorated) {
26832    this.$dropdownContainer.detach();
26833  };
26834
26835  AttachBody.prototype._bindContainerResultHandlers =
26836      function (decorated, container) {
26837
26838    // These should only be bound once
26839    if (this._containerResultsHandlersBound) {
26840      return;
26841    }
26842
26843    var self = this;
26844
26845    container.on('results:all', function () {
26846      self._positionDropdown();
26847      self._resizeDropdown();
26848    });
26849
26850    container.on('results:append', function () {
26851      self._positionDropdown();
26852      self._resizeDropdown();
26853    });
26854
26855    container.on('results:message', function () {
26856      self._positionDropdown();
26857      self._resizeDropdown();
26858    });
26859
26860    container.on('select', function () {
26861      self._positionDropdown();
26862      self._resizeDropdown();
26863    });
26864
26865    container.on('unselect', function () {
26866      self._positionDropdown();
26867      self._resizeDropdown();
26868    });
26869
26870    this._containerResultsHandlersBound = true;
26871  };
26872
26873  AttachBody.prototype._attachPositioningHandler =
26874      function (decorated, container) {
26875    var self = this;
26876
26877    var scrollEvent = 'scroll.select2.' + container.id;
26878    var resizeEvent = 'resize.select2.' + container.id;
26879    var orientationEvent = 'orientationchange.select2.' + container.id;
26880
26881    var $watchers = this.$container.parents().filter(Utils.hasScroll);
26882    $watchers.each(function () {
26883      Utils.StoreData(this, 'select2-scroll-position', {
26884        x: $(this).scrollLeft(),
26885        y: $(this).scrollTop()
26886      });
26887    });
26888
26889    $watchers.on(scrollEvent, function (ev) {
26890      var position = Utils.GetData(this, 'select2-scroll-position');
26891      $(this).scrollTop(position.y);
26892    });
26893
26894    $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
26895      function (e) {
26896      self._positionDropdown();
26897      self._resizeDropdown();
26898    });
26899  };
26900
26901  AttachBody.prototype._detachPositioningHandler =
26902      function (decorated, container) {
26903    var scrollEvent = 'scroll.select2.' + container.id;
26904    var resizeEvent = 'resize.select2.' + container.id;
26905    var orientationEvent = 'orientationchange.select2.' + container.id;
26906
26907    var $watchers = this.$container.parents().filter(Utils.hasScroll);
26908    $watchers.off(scrollEvent);
26909
26910    $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
26911  };
26912
26913  AttachBody.prototype._positionDropdown = function () {
26914    var $window = $(window);
26915
26916    var isCurrentlyAbove = this.$dropdown[0].classList
26917      .contains('select2-dropdown--above');
26918    var isCurrentlyBelow = this.$dropdown[0].classList
26919      .contains('select2-dropdown--below');
26920
26921    var newDirection = null;
26922
26923    var offset = this.$container.offset();
26924
26925    offset.bottom = offset.top + this.$container.outerHeight(false);
26926
26927    var container = {
26928      height: this.$container.outerHeight(false)
26929    };
26930
26931    container.top = offset.top;
26932    container.bottom = offset.top + container.height;
26933
26934    var dropdown = {
26935      height: this.$dropdown.outerHeight(false)
26936    };
26937
26938    var viewport = {
26939      top: $window.scrollTop(),
26940      bottom: $window.scrollTop() + $window.height()
26941    };
26942
26943    var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
26944    var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
26945
26946    var css = {
26947      left: offset.left,
26948      top: container.bottom
26949    };
26950
26951    // Determine what the parent element is to use for calculating the offset
26952    var $offsetParent = this.$dropdownParent;
26953
26954    // For statically positioned elements, we need to get the element
26955    // that is determining the offset
26956    if ($offsetParent.css('position') === 'static') {
26957      $offsetParent = $offsetParent.offsetParent();
26958    }
26959
26960    var parentOffset = {
26961      top: 0,
26962      left: 0
26963    };
26964
26965    if (
26966      $.contains(document.body, $offsetParent[0]) ||
26967      $offsetParent[0].isConnected
26968      ) {
26969      parentOffset = $offsetParent.offset();
26970    }
26971
26972    css.top -= parentOffset.top;
26973    css.left -= parentOffset.left;
26974
26975    if (!isCurrentlyAbove && !isCurrentlyBelow) {
26976      newDirection = 'below';
26977    }
26978
26979    if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
26980      newDirection = 'above';
26981    } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
26982      newDirection = 'below';
26983    }
26984
26985    if (newDirection == 'above' ||
26986      (isCurrentlyAbove && newDirection !== 'below')) {
26987      css.top = container.top - parentOffset.top - dropdown.height;
26988    }
26989
26990    if (newDirection != null) {
26991      this.$dropdown[0].classList.remove('select2-dropdown--below');
26992      this.$dropdown[0].classList.remove('select2-dropdown--above');
26993      this.$dropdown[0].classList.add('select2-dropdown--' + newDirection);
26994
26995      this.$container[0].classList.remove('select2-container--below');
26996      this.$container[0].classList.remove('select2-container--above');
26997      this.$container[0].classList.add('select2-container--' + newDirection);
26998    }
26999
27000    this.$dropdownContainer.css(css);
27001  };
27002
27003  AttachBody.prototype._resizeDropdown = function () {
27004    var css = {
27005      width: this.$container.outerWidth(false) + 'px'
27006    };
27007
27008    if (this.options.get('dropdownAutoWidth')) {
27009      css.minWidth = css.width;
27010      css.position = 'relative';
27011      css.width = 'auto';
27012    }
27013
27014    this.$dropdown.css(css);
27015  };
27016
27017  AttachBody.prototype._showDropdown = function (decorated) {
27018    this.$dropdownContainer.appendTo(this.$dropdownParent);
27019
27020    this._positionDropdown();
27021    this._resizeDropdown();
27022  };
27023
27024  return AttachBody;
27025});
27026
27027S2.define('select2/dropdown/minimumResultsForSearch',[
27028
27029], function () {
27030  function countResults (data) {
27031    var count = 0;
27032
27033    for (var d = 0; d < data.length; d++) {
27034      var item = data[d];
27035
27036      if (item.children) {
27037        count += countResults(item.children);
27038      } else {
27039        count++;
27040      }
27041    }
27042
27043    return count;
27044  }
27045
27046  function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
27047    this.minimumResultsForSearch = options.get('minimumResultsForSearch');
27048
27049    if (this.minimumResultsForSearch < 0) {
27050      this.minimumResultsForSearch = Infinity;
27051    }
27052
27053    decorated.call(this, $element, options, dataAdapter);
27054  }
27055
27056  MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
27057    if (countResults(params.data.results) < this.minimumResultsForSearch) {
27058      return false;
27059    }
27060
27061    return decorated.call(this, params);
27062  };
27063
27064  return MinimumResultsForSearch;
27065});
27066
27067S2.define('select2/dropdown/selectOnClose',[
27068  '../utils'
27069], function (Utils) {
27070  function SelectOnClose () { }
27071
27072  SelectOnClose.prototype.bind = function (decorated, container, $container) {
27073    var self = this;
27074
27075    decorated.call(this, container, $container);
27076
27077    container.on('close', function (params) {
27078      self._handleSelectOnClose(params);
27079    });
27080  };
27081
27082  SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
27083    if (params && params.originalSelect2Event != null) {
27084      var event = params.originalSelect2Event;
27085
27086      // Don't select an item if the close event was triggered from a select or
27087      // unselect event
27088      if (event._type === 'select' || event._type === 'unselect') {
27089        return;
27090      }
27091    }
27092
27093    var $highlightedResults = this.getHighlightedResults();
27094
27095    // Only select highlighted results
27096    if ($highlightedResults.length < 1) {
27097      return;
27098    }
27099
27100    var data = Utils.GetData($highlightedResults[0], 'data');
27101
27102    // Don't re-select already selected resulte
27103    if (
27104      (data.element != null && data.element.selected) ||
27105      (data.element == null && data.selected)
27106    ) {
27107      return;
27108    }
27109
27110    this.trigger('select', {
27111        data: data
27112    });
27113  };
27114
27115  return SelectOnClose;
27116});
27117
27118S2.define('select2/dropdown/closeOnSelect',[
27119
27120], function () {
27121  function CloseOnSelect () { }
27122
27123  CloseOnSelect.prototype.bind = function (decorated, container, $container) {
27124    var self = this;
27125
27126    decorated.call(this, container, $container);
27127
27128    container.on('select', function (evt) {
27129      self._selectTriggered(evt);
27130    });
27131
27132    container.on('unselect', function (evt) {
27133      self._selectTriggered(evt);
27134    });
27135  };
27136
27137  CloseOnSelect.prototype._selectTriggered = function (_, evt) {
27138    var originalEvent = evt.originalEvent;
27139
27140    // Don't close if the control key is being held
27141    if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) {
27142      return;
27143    }
27144
27145    this.trigger('close', {
27146      originalEvent: originalEvent,
27147      originalSelect2Event: evt
27148    });
27149  };
27150
27151  return CloseOnSelect;
27152});
27153
27154S2.define('select2/dropdown/dropdownCss',[
27155  '../utils'
27156], function (Utils) {
27157  function DropdownCSS () { }
27158
27159  DropdownCSS.prototype.render = function (decorated) {
27160    var $dropdown = decorated.call(this);
27161
27162    var dropdownCssClass = this.options.get('dropdownCssClass') || '';
27163
27164    if (dropdownCssClass.indexOf(':all:') !== -1) {
27165      dropdownCssClass = dropdownCssClass.replace(':all:', '');
27166
27167      Utils.copyNonInternalCssClasses($dropdown[0], this.$element[0]);
27168    }
27169
27170    $dropdown.addClass(dropdownCssClass
vendor: 10,812 bytes, lines 27170-27592
27170);
27171
27172    return $dropdown;
27173  };
27174
27175  return DropdownCSS;
27176});
27177
27178S2.define('select2/dropdown/tagsSearchHighlight',[
27179  '../utils'
27180], function (Utils) {
27181  function TagsSearchHighlight () { }
27182
27183  TagsSearchHighlight.prototype.highlightFirstItem = function (decorated) {
27184    var $options = this.$results
27185    .find(
27186      '.select2-results__option--selectable' +
27187      ':not(.select2-results__option--selected)'
27188    );
27189
27190    if ($options.length > 0) {
27191      var $firstOption = $options.first();
27192      var data = Utils.GetData($firstOption[0], 'data');
27193      var firstElement = data.element;
27194
27195      if (firstElement && firstElement.getAttribute) {
27196        if (firstElement.getAttribute('data-select2-tag') === 'true') {
27197          $firstOption.trigger('mouseenter');
27198
27199          return;
27200        }
27201      }
27202    }
27203
27204    decorated.call(this);
27205  };
27206
27207  return TagsSearchHighlight;
27208});
27209
27210S2.define('select2/i18n/en',[],function () {
27211  // English
27212  return {
27213    errorLoading: function () {
27214      return 'The results could not be loaded.';
27215    },
27216    inputTooLong: function (args) {
27217      var overChars = args.input.length - args.maximum;
27218
27219      var message = 'Please delete ' + overChars + ' character';
27220
27221      if (overChars != 1) {
27222        message += 's';
27223      }
27224
27225      return message;
27226    },
27227    inputTooShort: function (args) {
27228      var remainingChars = args.minimum - args.input.length;
27229
27230      var message = 'Please enter ' + remainingChars + ' or more characters';
27231
27232      return message;
27233    },
27234    loadingMore: function () {
27235      return 'Loading more results…';
27236    },
27237    maximumSelected: function (args) {
27238      var message = 'You can only select ' + args.maximum + ' item';
27239
27240      if (args.maximum != 1) {
27241        message += 's';
27242      }
27243
27244      return message;
27245    },
27246    noResults: function () {
27247      return 'No results found';
27248    },
27249    searching: function () {
27250      return 'Searching…';
27251    },
27252    removeAllItems: function () {
27253      return 'Remove all items';
27254    },
27255    removeItem: function () {
27256      return 'Remove item';
27257    },
27258    search: function() {
27259      return 'Search';
27260    }
27261  };
27262});
27263
27264S2.define('select2/defaults',[
27265  'jquery',
27266
27267  './results',
27268
27269  './selection/single',
27270  './selection/multiple',
27271  './selection/placeholder',
27272  './selection/allowClear',
27273  './selection/search',
27274  './selection/selectionCss',
27275  './selection/eventRelay',
27276
27277  './utils',
27278  './translation',
27279  './diacritics',
27280
27281  './data/select',
27282  './data/array',
27283  './data/ajax',
27284  './data/tags',
27285  './data/tokenizer',
27286  './data/minimumInputLength',
27287  './data/maximumInputLength',
27288  './data/maximumSelectionLength',
27289
27290  './dropdown',
27291  './dropdown/search',
27292  './dropdown/hidePlaceholder',
27293  './dropdown/infiniteScroll',
27294  './dropdown/attachBody',
27295  './dropdown/minimumResultsForSearch',
27296  './dropdown/selectOnClose',
27297  './dropdown/closeOnSelect',
27298  './dropdown/dropdownCss',
27299  './dropdown/tagsSearchHighlight',
27300
27301  './i18n/en'
27302], function ($,
27303
27304             ResultsList,
27305
27306             SingleSelection, MultipleSelection, Placeholder, AllowClear,
27307             SelectionSearch, SelectionCSS, EventRelay,
27308
27309             Utils, Translation, DIACRITICS,
27310
27311             SelectData, ArrayData, AjaxData, Tags, Tokenizer,
27312             MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
27313
27314             Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
27315             AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
27316             DropdownCSS, TagsSearchHighlight,
27317
27318             EnglishTranslation) {
27319  function Defaults () {
27320    this.reset();
27321  }
27322
27323  Defaults.prototype.apply = function (options) {
27324    options = $.extend(true, {}, this.defaults, options);
27325
27326    if (options.dataAdapter == null) {
27327      if (options.ajax != null) {
27328        options.dataAdapter = AjaxData;
27329      } else if (options.data != null) {
27330        options.dataAdapter = ArrayData;
27331      } else {
27332        options.dataAdapter = SelectData;
27333      }
27334
27335      if (options.minimumInputLength > 0) {
27336        options.dataAdapter = Utils.Decorate(
27337          options.dataAdapter,
27338          MinimumInputLength
27339        );
27340      }
27341
27342      if (options.maximumInputLength > 0) {
27343        options.dataAdapter = Utils.Decorate(
27344          options.dataAdapter,
27345          MaximumInputLength
27346        );
27347      }
27348
27349      if (options.maximumSelectionLength > 0) {
27350        options.dataAdapter = Utils.Decorate(
27351          options.dataAdapter,
27352          MaximumSelectionLength
27353        );
27354      }
27355
27356      if (options.tags) {
27357        options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
27358      }
27359
27360      if (options.tokenSeparators != null || options.tokenizer != null) {
27361        options.dataAdapter = Utils.Decorate(
27362          options.dataAdapter,
27363          Tokenizer
27364        );
27365      }
27366    }
27367
27368    if (options.resultsAdapter == null) {
27369      options.resultsAdapter = ResultsList;
27370
27371      if (options.ajax != null) {
27372        options.resultsAdapter = Utils.Decorate(
27373          options.resultsAdapter,
27374          InfiniteScroll
27375        );
27376      }
27377
27378      if (options.placeholder != null) {
27379        options.resultsAdapter = Utils.Decorate(
27380          options.resultsAdapter,
27381          HidePlaceholder
27382        );
27383      }
27384
27385      if (options.selectOnClose) {
27386        options.resultsAdapter = Utils.Decorate(
27387          options.resultsAdapter,
27388          SelectOnClose
27389        );
27390      }
27391
27392      if (options.tags) {
27393        options.resultsAdapter = Utils.Decorate(
27394          options.resultsAdapter,
27395          TagsSearchHighlight
27396        );
27397      }
27398    }
27399
27400    if (options.dropdownAdapter == null) {
27401      if (options.multiple) {
27402        options.dropdownAdapter = Dropdown;
27403      } else {
27404        var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
27405
27406        options.dropdownAdapter = SearchableDropdown;
27407      }
27408
27409      if (options.minimumResultsForSearch !== 0) {
27410        options.dropdownAdapter = Utils.Decorate(
27411          options.dropdownAdapter,
27412          MinimumResultsForSearch
27413        );
27414      }
27415
27416      if (options.closeOnSelect) {
27417        options.dropdownAdapter = Utils.Decorate(
27418          options.dropdownAdapter,
27419          CloseOnSelect
27420        );
27421      }
27422
27423      if (options.dropdownCssClass != null) {
27424        options.dropdownAdapter = Utils.Decorate(
27425          options.dropdownAdapter,
27426          DropdownCSS
27427        );
27428      }
27429
27430      options.dropdownAdapter = Utils.Decorate(
27431        options.dropdownAdapter,
27432        AttachBody
27433      );
27434    }
27435
27436    if (options.selectionAdapter == null) {
27437      if (options.multiple) {
27438        options.selectionAdapter = MultipleSelection;
27439      } else {
27440        options.selectionAdapter = SingleSelection;
27441      }
27442
27443      // Add the placeholder mixin if a placeholder was specified
27444      if (options.placeholder != null) {
27445        options.selectionAdapter = Utils.Decorate(
27446          options.selectionAdapter,
27447          Placeholder
27448        );
27449      }
27450
27451      if (options.allowClear) {
27452        options.selectionAdapter = Utils.Decorate(
27453          options.selectionAdapter,
27454          AllowClear
27455        );
27456      }
27457
27458      if (options.multiple) {
27459        options.selectionAdapter = Utils.Decorate(
27460          options.selectionAdapter,
27461          SelectionSearch
27462        );
27463      }
27464
27465      if (options.selectionCssClass != null) {
27466        options.selectionAdapter = Utils.Decorate(
27467          options.selectionAdapter,
27468          SelectionCSS
27469        );
27470      }
27471
27472      options.selectionAdapter = Utils.Decorate(
27473        options.selectionAdapter,
27474        EventRelay
27475      );
27476    }
27477
27478    // If the defaults were not previously applied from an element, it is
27479    // possible for the language option to have not been resolved
27480    options.language = this._resolveLanguage(options.language);
27481
27482    // Always fall back to English since it will always be complete
27483    options.language.push('en');
27484
27485    var uniqueLanguages = [];
27486
27487    for (var l = 0; l < options.language.length; l++) {
27488      var language = options.language[l];
27489
27490      if (uniqueLanguages.indexOf(language) === -1) {
27491        uniqueLanguages.push(language);
27492      }
27493    }
27494
27495    options.language = uniqueLanguages;
27496
27497    options.translations = this._processTranslations(
27498      options.language,
27499      options.debug
27500    );
27501
27502    return options;
27503  };
27504
27505  Defaults.prototype.reset = function () {
27506    function stripDiacritics (text) {
27507      // Used 'uni range + named function' from http://jsperf.com/diacritics/18
27508      function match(a) {
27509        return DIACRITICS[a] || a;
27510      }
27511
27512      return text.replace(/[^\u0000-\u007E]/g, match);
27513    }
27514
27515    function matcher (params, data) {
27516      // Always return the object if there is nothing to compare
27517      if (params.term == null || params.term.trim() === '') {
27518        return data;
27519      }
27520
27521      // Do a recursive check for options with children
27522      if (data.children && data.children.length > 0) {
27523        // Clone the data object if there are children
27524        // This is required as we modify the object to remove any non-matches
27525        var match = $.extend(true, {}, data);
27526
27527        // Check each child of the option
27528        for (var c = data.children.length - 1; c >= 0; c--) {
27529          var child = data.children[c];
27530
27531          var matches = matcher(params, child);
27532
27533          // If there wasn't a match, remove the object in the array
27534          if (matches == null) {
27535            match.children.splice(c, 1);
27536          }
27537        }
27538
27539        // If any children matched, return the new object
27540        if (match.children.length > 0) {
27541          return match;
27542        }
27543
27544        // If there were no matching children, check just the plain object
27545        return matcher(params, match);
27546      }
27547
27548      var original = stripDiacritics(data.text).toUpperCase();
27549      var term = stripDiacritics(params.term).toUpperCase();
27550
27551      // Check if the text contains the term
27552      if (original.indexOf(term) > -1) {
27553        return data;
27554      }
27555
27556      // If it doesn't contain the term, don't return anything
27557      return null;
27558    }
27559
27560    this.defaults = {
27561      amdLanguageBase: './i18n/',
27562      autocomplete: 'off',
27563      closeOnSelect: true,
27564      debug: false,
27565      dropdownAutoWidth: false,
27566      escapeMarkup: Utils.escapeMarkup,
27567      language: {},
27568      matcher: matcher,
27569      minimumInputLength: 0,
27570      maximumInputLength: 0,
27571      maximumSelectionLength: 0,
27572      minimumResultsForSearch: 0,
27573      selectOnClose: false,
27574      scrollAfterSelect: false,
27575      sorter: function (data) {
27576        return data;
27577      },
27578      templateResult: function (result) {
27579        return result.text;
27580      },
27581      templateSelection: function (selection) {
27582        return selection.text;
27583      },
27584      theme: 'default',
27585      width: 'resolve'
27586    };
27587  };
27588
27589  Defaults.prototype.applyFromElement = function (options, $element) {
27590    var optionLanguage = options.language;
27591    var defaultLanguage = this.defaults.language;
27592    var elementLanguage = $element
vendor: 19,057 bytes, lines 27592-28323
27592.prop('lang');
27593    var parentLanguage = $element.closest('[lang]').prop('lang');
27594
27595    var languages = Array.prototype.concat.call(
27596      this._resolveLanguage(elementLanguage),
27597      this._resolveLanguage(optionLanguage),
27598      this._resolveLanguage(defaultLanguage),
27599      this._resolveLanguage(parentLanguage)
27600    );
27601
27602    options.language = languages;
27603
27604    return options;
27605  };
27606
27607  Defaults.prototype._resolveLanguage = function (language) {
27608    if (!language) {
27609      return [];
27610    }
27611
27612    if ($.isEmptyObject(language)) {
27613      return [];
27614    }
27615
27616    if ($.isPlainObject(language)) {
27617      return [language];
27618    }
27619
27620    var languages;
27621
27622    if (!Array.isArray(language)) {
27623      languages = [language];
27624    } else {
27625      languages = language;
27626    }
27627
27628    var resolvedLanguages = [];
27629
27630    for (var l = 0; l < languages.length; l++) {
27631      resolvedLanguages.push(languages[l]);
27632
27633      if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) {
27634        // Extract the region information if it is included
27635        var languageParts = languages[l].split('-');
27636        var baseLanguage = languageParts[0];
27637
27638        resolvedLanguages.push(baseLanguage);
27639      }
27640    }
27641
27642    return resolvedLanguages;
27643  };
27644
27645  Defaults.prototype._processTranslations = function (languages, debug) {
27646    var translations = new Translation();
27647
27648    for (var l = 0; l < languages.length; l++) {
27649      var languageData = new Translation();
27650
27651      var language = languages[l];
27652
27653      if (typeof language === 'string') {
27654        try {
27655          // Try to load it with the original name
27656          languageData = Translation.loadPath(language);
27657        } catch (e) {
27658          try {
27659            // If we couldn't load it, check if it wasn't the full path
27660            language = this.defaults.amdLanguageBase + language;
27661            languageData = Translation.loadPath(language);
27662          } catch (ex) {
27663            // The translation could not be loaded at all. Sometimes this is
27664            // because of a configuration problem, other times this can be
27665            // because of how Select2 helps load all possible translation files
27666            if (debug && window.console && console.warn) {
27667              console.warn(
27668                'Select2: The language file for "' + language + '" could ' +
27669                'not be automatically loaded. A fallback will be used instead.'
27670              );
27671            }
27672          }
27673        }
27674      } else if ($.isPlainObject(language)) {
27675        languageData = new Translation(language);
27676      } else {
27677        languageData = language;
27678      }
27679
27680      translations.extend(languageData);
27681    }
27682
27683    return translations;
27684  };
27685
27686  Defaults.prototype.set = function (key, value) {
27687    var camelKey = $.camelCase(key);
27688
27689    var data = {};
27690    data[camelKey] = value;
27691
27692    var convertedData = Utils._convertData(data);
27693
27694    $.extend(true, this.defaults, convertedData);
27695  };
27696
27697  var defaults = new Defaults();
27698
27699  return defaults;
27700});
27701
27702S2.define('select2/options',[
27703  'jquery',
27704  './defaults',
27705  './utils'
27706], function ($, Defaults, Utils) {
27707  function Options (options, $element) {
27708    this.options = options;
27709
27710    if ($element != null) {
27711      this.fromElement($element);
27712    }
27713
27714    if ($element != null) {
27715      this.options = Defaults.applyFromElement(this.options, $element);
27716    }
27717
27718    this.options = Defaults.apply(this.options);
27719  }
27720
27721  Options.prototype.fromElement = function ($e) {
27722    var excludedData = ['select2'];
27723
27724    if (this.options.multiple == null) {
27725      this.options.multiple = $e.prop('multiple');
27726    }
27727
27728    if (this.options.disabled == null) {
27729      this.options.disabled = $e.prop('disabled');
27730    }
27731
27732    if (this.options.autocomplete == null && $e.prop('autocomplete')) {
27733      this.options.autocomplete = $e.prop('autocomplete');
27734    }
27735
27736    if (this.options.dir == null) {
27737      if ($e.prop('dir')) {
27738        this.options.dir = $e.prop('dir');
27739      } else if ($e.closest('[dir]').prop('dir')) {
27740        this.options.dir = $e.closest('[dir]').prop('dir');
27741      } else {
27742        this.options.dir = 'ltr';
27743      }
27744    }
27745
27746    $e.prop('disabled', this.options.disabled);
27747    $e.prop('multiple', this.options.multiple);
27748
27749    if (Utils.GetData($e[0], 'select2Tags')) {
27750      if (this.options.debug && window.console && console.warn) {
27751        console.warn(
27752          'Select2: The `data-select2-tags` attribute has been changed to ' +
27753          'use the `data-data` and `data-tags="true"` attributes and will be ' +
27754          'removed in future versions of Select2.'
27755        );
27756      }
27757
27758      Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
27759      Utils.StoreData($e[0], 'tags', true);
27760    }
27761
27762    if (Utils.GetData($e[0], 'ajaxUrl')) {
27763      if (this.options.debug && window.console && console.warn) {
27764        console.warn(
27765          'Select2: The `data-ajax-url` attribute has been changed to ' +
27766          '`data-ajax--url` and support for the old attribute will be removed' +
27767          ' in future versions of Select2.'
27768        );
27769      }
27770
27771      $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
27772      Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
27773    }
27774
27775    var dataset = {};
27776
27777    function upperCaseLetter(_, letter) {
27778      return letter.toUpperCase();
27779    }
27780
27781    // Pre-load all of the attributes which are prefixed with `data-`
27782    for (var attr = 0; attr < $e[0].attributes.length; attr++) {
27783      var attributeName = $e[0].attributes[attr].name;
27784      var prefix = 'data-';
27785
27786      if (attributeName.substr(0, prefix.length) == prefix) {
27787        // Get the contents of the attribute after `data-`
27788        var dataName = attributeName.substring(prefix.length);
27789
27790        // Get the data contents from the consistent source
27791        // This is more than likely the jQuery data helper
27792        var dataValue = Utils.GetData($e[0], dataName);
27793
27794        // camelCase the attribute name to match the spec
27795        var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter);
27796
27797        // Store the data attribute contents into the dataset since
27798        dataset[camelDataName] = dataValue;
27799      }
27800    }
27801
27802    // Prefer the element's `dataset` attribute if it exists
27803    // jQuery 1.x does not correctly handle data attributes with multiple dashes
27804    if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
27805      dataset = $.extend(true, {}, $e[0].dataset, dataset);
27806    }
27807
27808    // Prefer our internal data cache if it exists
27809    var data = $.extend(true, {}, Utils.GetData($e[0]), dataset);
27810
27811    data = Utils._convertData(data);
27812
27813    for (var key in data) {
27814      if (excludedData.indexOf(key) > -1) {
27815        continue;
27816      }
27817
27818      if ($.isPlainObject(this.options[key])) {
27819        $.extend(this.options[key], data[key]);
27820      } else {
27821        this.options[key] = data[key];
27822      }
27823    }
27824
27825    return this;
27826  };
27827
27828  Options.prototype.get = function (key) {
27829    return this.options[key];
27830  };
27831
27832  Options.prototype.set = function (key, val) {
27833    this.options[key] = val;
27834  };
27835
27836  return Options;
27837});
27838
27839S2.define('select2/core',[
27840  'jquery',
27841  './options',
27842  './utils',
27843  './keys'
27844], function ($, Options, Utils, KEYS) {
27845  var Select2 = function ($element, options) {
27846    if (Utils.GetData($element[0], 'select2') != null) {
27847      Utils.GetData($element[0], 'select2').destroy();
27848    }
27849
27850    this.$element = $element;
27851
27852    this.id = this._generateId($element);
27853
27854    options = options || {};
27855
27856    this.options = new Options(options, $element);
27857
27858    Select2.__super__.constructor.call(this);
27859
27860    // Set up the tabindex
27861
27862    var tabindex = $element.attr('tabindex') || 0;
27863    Utils.StoreData($element[0], 'old-tabindex', tabindex);
27864    $element.attr('tabindex', '-1');
27865
27866    // Set up containers and adapters
27867
27868    var DataAdapter = this.options.get('dataAdapter');
27869    this.dataAdapter = new DataAdapter($element, this.options);
27870
27871    var $container = this.render();
27872
27873    this._placeContainer($container);
27874
27875    var SelectionAdapter = this.options.get('selectionAdapter');
27876    this.selection = new SelectionAdapter($element, this.options);
27877    this.$selection = this.selection.render();
27878
27879    this.selection.position(this.$selection, $container);
27880
27881    var DropdownAdapter = this.options.get('dropdownAdapter');
27882    this.dropdown = new DropdownAdapter($element, this.options);
27883    this.$dropdown = this.dropdown.render();
27884
27885    this.dropdown.position(this.$dropdown, $container);
27886
27887    var ResultsAdapter = this.options.get('resultsAdapter');
27888    this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
27889    this.$results = this.results.render();
27890
27891    this.results.position(this.$results, this.$dropdown);
27892
27893    // Bind events
27894
27895    var self = this;
27896
27897    // Bind the container to all of the adapters
27898    this._bindAdapters();
27899
27900    // Register any DOM event handlers
27901    this._registerDomEvents();
27902
27903    // Register any internal event handlers
27904    this._registerDataEvents();
27905    this._registerSelectionEvents();
27906    this._registerDropdownEvents();
27907    this._registerResultsEvents();
27908    this._registerEvents();
27909
27910    // Set the initial state
27911    this.dataAdapter.current(function (initialData) {
27912      self.trigger('selection:update', {
27913        data: initialData
27914      });
27915    });
27916
27917    // Hide the original select
27918    $element[0].classList.add('select2-hidden-accessible');
27919    $element.attr('aria-hidden', 'true');
27920
27921    // Synchronize any monitored attributes
27922    this._syncAttributes();
27923
27924    Utils.StoreData($element[0], 'select2', this);
27925
27926    // Ensure backwards compatibility with $element.data('select2').
27927    $element.data('select2', this);
27928  };
27929
27930  Utils.Extend(Select2, Utils.Observable);
27931
27932  Select2.prototype._generateId = function ($element) {
27933    var id = '';
27934
27935    if ($element.attr('id') != null) {
27936      id = $element.attr('id');
27937    } else if ($element.attr('name') != null) {
27938      id = $element.attr('name') + '-' + Utils.generateChars(2);
27939    } else {
27940      id = Utils.generateChars(4);
27941    }
27942
27943    id = id.replace(/(:|\.|\[|\]|,)/g, '');
27944    id = 'select2-' + id;
27945
27946    return id;
27947  };
27948
27949  Select2.prototype._placeContainer = function ($container) {
27950    $container.insertAfter(this.$element);
27951
27952    var width = this._resolveWidth(this.$element, this.options.get('width'));
27953
27954    if (width != null) {
27955      $container.css('width', width);
27956    }
27957  };
27958
27959  Select2.prototype._resolveWidth = function ($element, method) {
27960    var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
27961
27962    if (method == 'resolve') {
27963      var styleWidth = this._resolveWidth($element, 'style');
27964
27965      if (styleWidth != null) {
27966        return styleWidth;
27967      }
27968
27969      return this._resolveWidth($element, 'element');
27970    }
27971
27972    if (method == 'element') {
27973      var elementWidth = $element.outerWidth(false);
27974
27975      if (elementWidth <= 0) {
27976        return 'auto';
27977      }
27978
27979      return elementWidth + 'px';
27980    }
27981
27982    if (method == 'style') {
27983      var style = $element.attr('style');
27984
27985      if (typeof(style) !== 'string') {
27986        return null;
27987      }
27988
27989      var attrs = style.split(';');
27990
27991      for (var i = 0, l = attrs.length; i < l; i = i + 1) {
27992        var attr = attrs[i].replace(/\s/g, '');
27993        var matches = attr.match(WIDTH);
27994
27995        if (matches !== null && matches.length >= 1) {
27996          return matches[1];
27997        }
27998      }
27999
28000      return null;
28001    }
28002
28003    if (method == 'computedstyle') {
28004      var computedStyle = window.getComputedStyle($element[0]);
28005
28006      return computedStyle.width;
28007    }
28008
28009    return method;
28010  };
28011
28012  Select2.prototype._bindAdapters = function () {
28013    this.dataAdapter.bind(this, this.$container);
28014    this.selection.bind(this, this.$container);
28015
28016    this.dropdown.bind(this, this.$container);
28017    this.results.bind(this, this.$container);
28018  };
28019
28020  Select2.prototype._registerDomEvents = function () {
28021    var self = this;
28022
28023    this.$element.on('change.select2', function () {
28024      self.dataAdapter.current(function (data) {
28025        self.trigger('selection:update', {
28026          data: data
28027        });
28028      });
28029    });
28030
28031    this.$element.on('focus.select2', function (evt) {
28032      self.trigger('focus', evt);
28033    });
28034
28035    this._syncA = Utils.bind(this._syncAttributes, this);
28036    this._syncS = Utils.bind(this._syncSubtree, this);
28037
28038    this._observer = new window.MutationObserver(function (mutations) {
28039      self._syncA();
28040      self._syncS(mutations);
28041    });
28042    this._observer.observe(this.$element[0], {
28043      attributes: true,
28044      childList: true,
28045      subtree: false
28046    });
28047  };
28048
28049  Select2.prototype._registerDataEvents = function () {
28050    var self = this;
28051
28052    this.dataAdapter.on('*', function (name, params) {
28053      self.trigger(name, params);
28054    });
28055  };
28056
28057  Select2.prototype._registerSelectionEvents = function () {
28058    var self = this;
28059    var nonRelayEvents = ['toggle', 'focus'];
28060
28061    this.selection.on('toggle', function () {
28062      self.toggleDropdown();
28063    });
28064
28065    this.selection.on('focus', function (params) {
28066      self.focus(params);
28067    });
28068
28069    this.selection.on('*', function (name, params) {
28070      if (nonRelayEvents.indexOf(name) !== -1) {
28071        return;
28072      }
28073
28074      self.trigger(name, params);
28075    });
28076  };
28077
28078  Select2.prototype._registerDropdownEvents = function () {
28079    var self = this;
28080
28081    this.dropdown.on('*', function (name, params) {
28082      self.trigger(name, params);
28083    });
28084  };
28085
28086  Select2.prototype._registerResultsEvents = function () {
28087    var self = this;
28088
28089    this.results.on('*', function (name, params) {
28090      self.trigger(name, params);
28091    });
28092  };
28093
28094  Select2.prototype._registerEvents = function () {
28095    var self = this;
28096
28097    this.on('open', function () {
28098      self.$container[0].classList.add('select2-container--open');
28099    });
28100
28101    this.on('close', function () {
28102      self.$container[0].classList.remove('select2-container--open');
28103    });
28104
28105    this.on('enable', function () {
28106      self.$container[0].classList.remove('select2-container--disabled');
28107    });
28108
28109    this.on('disable', function () {
28110      self.$container[0].classList.add('select2-container--disabled');
28111    });
28112
28113    this.on('blur', function () {
28114      self.$container[0].classList.remove('select2-container--focus');
28115    });
28116
28117    this.on('query', function (params) {
28118      if (!self.isOpen()) {
28119        self.trigger('open', {});
28120      }
28121
28122      this.dataAdapter.query(params, function (data) {
28123        self.trigger('results:all', {
28124          data: data,
28125          query: params
28126        });
28127      });
28128    });
28129
28130    this.on('query:append', function (params) {
28131      this.dataAdapter.query(params, function (data) {
28132        self.trigger('results:append', {
28133          data: data,
28134          query: params
28135        });
28136      });
28137    });
28138
28139    this.on('keypress', function (evt) {
28140      var key = evt.which;
28141
28142      if (self.isOpen()) {
28143        if (key === KEYS.ESC || (key === KEYS.UP && evt.altKey)) {
28144          self.close(evt);
28145
28146          evt.preventDefault();
28147        } else if (key === KEYS.ENTER || key === KEYS.TAB) {
28148          self.trigger('results:select', {});
28149
28150          evt.preventDefault();
28151        } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
28152          self.trigger('results:toggle', {});
28153
28154          evt.preventDefault();
28155        } else if (key === KEYS.UP) {
28156          self.trigger('results:previous', {});
28157
28158          evt.preventDefault();
28159        } else if (key === KEYS.DOWN) {
28160          self.trigger('results:next', {});
28161
28162          evt.preventDefault();
28163        }
28164      } else {
28165        if (key === KEYS.ENTER || key === KEYS.SPACE ||
28166            (key === KEYS.DOWN && evt.altKey)) {
28167          self.open();
28168
28169          evt.preventDefault();
28170        }
28171      }
28172    });
28173  };
28174
28175  Select2.prototype._syncAttributes = function () {
28176    this.options.set('disabled', this.$element.prop('disabled'));
28177
28178    if (this.isDisabled()) {
28179      if (this.isOpen()) {
28180        this.close();
28181      }
28182
28183      this.trigger('disable', {});
28184    } else {
28185      this.trigger('enable', {});
28186    }
28187  };
28188
28189  Select2.prototype._isChangeMutation = function (mutations) {
28190    var self = this;
28191
28192    if (mutations.addedNodes && mutations.addedNodes.length > 0) {
28193      for (var n = 0; n < mutations.addedNodes.length; n++) {
28194        var node = mutations.addedNodes[n];
28195
28196        if (node.selected) {
28197          return true;
28198        }
28199      }
28200    } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
28201      return true;
28202    } else if (Array.isArray(mutations)) {
28203      return mutations.some(function (mutation) {
28204        return self._isChangeMutation(mutation);
28205      });
28206    }
28207
28208    return false;
28209  };
28210
28211  Select2.prototype._syncSubtree = function (mutations) {
28212    var changed = this._isChangeMutation(mutations);
28213    var self = this;
28214
28215    // Only re-pull the data if we think there is a change
28216    if (changed) {
28217      this.dataAdapter.current(function (currentData) {
28218        self.trigger('selection:update', {
28219          data: currentData
28220        });
28221      });
28222    }
28223  };
28224
28225  /**
28226   * Override the trigger method to automatically trigger pre-events when
28227   * there are events that can be prevented.
28228   */
28229  Select2.prototype.trigger = function (name, args) {
28230    var actualTrigger = Select2.__super__.trigger;
28231    var preTriggerMap = {
28232      'open': 'opening',
28233      'close': 'closing',
28234      'select': 'selecting',
28235      'unselect': 'unselecting',
28236      'clear': 'clearing'
28237    };
28238
28239    if (args === undefined) {
28240      args = {};
28241    }
28242
28243    if (name in preTriggerMap) {
28244      var preTriggerName = preTriggerMap[name];
28245      var preTriggerArgs = {
28246        prevented: false,
28247        name: name,
28248        args: args
28249      };
28250
28251      actualTrigger.call(this, preTriggerName, preTriggerArgs);
28252
28253      if (preTriggerArgs.prevented) {
28254        args.prevented = true;
28255
28256        return;
28257      }
28258    }
28259
28260    actualTrigger.call(this, name, args);
28261  };
28262
28263  Select2.prototype.toggleDropdown = function () {
28264    if (this.isDisabled()) {
28265      return;
28266    }
28267
28268    if (this.isOpen()) {
28269      this.close();
28270    } else {
28271      this.open();
28272    }
28273  };
28274
28275  Select2.prototype.open = function () {
28276    if (this.isOpen()) {
28277      return;
28278    }
28279
28280    if (this.isDisabled()) {
28281      return;
28282    }
28283
28284    this.trigger('query', {});
28285  };
28286
28287  Select2.prototype.close = function (evt) {
28288    if (!this.isOpen()) {
28289      return;
28290    }
28291
28292    this.trigger('close', { originalEvent : evt });
28293  };
28294
28295  /**
28296   * Helper method to abstract the "enabled" (not "disabled") state of this
28297   * object.
28298   *
28299   * @return {true} if the instance is not disabled.
28300   * @return {false} if the instance is disabled.
28301   */
28302  Select2.prototype.isEnabled = function () {
28303    return !this.isDisabled();
28304  };
28305
28306  /**
28307   * Helper method to abstract the "disabled" state of this object.
28308   *
28309   * @return {true} if the disabled option is true.
28310   * @return {false} if the disabled option is false.
28311   */
28312  Select2.prototype.isDisabled = function () {
28313    return this.options.get('disabled');
28314  };
28315
28316  Select2.prototype.isOpen = function () {
28317    return this.$container[0].classList.contains('select2-container--open');
28318  };
28319
28320  Select2.prototype.hasFocus = function () {
28321    return this.$container[0].classList.contains('select2-container--focus');
28322  };
28323
vendor: 6,505 bytes, lines 28324-28561
28324  Select2.prototype.focus = function (data) {
28325    // No need to re-trigger focus events if we are already focused
28326    if (this.hasFocus()) {
28327      return;
28328    }
28329
28330    this.$container[0].classList.add('select2-container--focus');
28331    this.trigger('focus', {});
28332  };
28333
28334  Select2.prototype.enable = function (args) {
28335    if (this.options.get('debug') && window.console && console.warn) {
28336      console.warn(
28337        'Select2: The `select2("enable")` method has been deprecated and will' +
28338        ' be removed in later Select2 versions. Use $element.prop("disabled")' +
28339        ' instead.'
28340      );
28341    }
28342
28343    if (args == null || args.length === 0) {
28344      args = [true];
28345    }
28346
28347    var disabled = !args[0];
28348
28349    this.$element.prop('disabled', disabled);
28350  };
28351
28352  Select2.prototype.data = function () {
28353    if (this.options.get('debug') &&
28354        arguments.length > 0 && window.console && console.warn) {
28355      console.warn(
28356        'Select2: Data can no longer be set using `select2("data")`. You ' +
28357        'should consider setting the value instead using `$element.val()`.'
28358      );
28359    }
28360
28361    var data = [];
28362
28363    this.dataAdapter.current(function (currentData) {
28364      data = currentData;
28365    });
28366
28367    return data;
28368  };
28369
28370  Select2.prototype.val = function (args) {
28371    if (this.options.get('debug') && window.console && console.warn) {
28372      console.warn(
28373        'Select2: The `select2("val")` method has been deprecated and will be' +
28374        ' removed in later Select2 versions. Use $element.val() instead.'
28375      );
28376    }
28377
28378    if (args == null || args.length === 0) {
28379      return this.$element.val();
28380    }
28381
28382    var newVal = args[0];
28383
28384    if (Array.isArray(newVal)) {
28385      newVal = newVal.map(function (obj) {
28386        return obj.toString();
28387      });
28388    }
28389
28390    this.$element.val(newVal).trigger('input').trigger('change');
28391  };
28392
28393  Select2.prototype.destroy = function () {
28394    Utils.RemoveData(this.$container[0]);
28395    this.$container.remove();
28396
28397    this._observer.disconnect();
28398    this._observer = null;
28399
28400    this._syncA = null;
28401    this._syncS = null;
28402
28403    this.$element.off('.select2');
28404    this.$element.attr('tabindex',
28405    Utils.GetData(this.$element[0], 'old-tabindex'));
28406
28407    this.$element[0].classList.remove('select2-hidden-accessible');
28408    this.$element.attr('aria-hidden', 'false');
28409    Utils.RemoveData(this.$element[0]);
28410    this.$element.removeData('select2');
28411
28412    this.dataAdapter.destroy();
28413    this.selection.destroy();
28414    this.dropdown.destroy();
28415    this.results.destroy();
28416
28417    this.dataAdapter = null;
28418    this.selection = null;
28419    this.dropdown = null;
28420    this.results = null;
28421  };
28422
28423  Select2.prototype.render = function () {
28424    var $container = $(
28425      '<span class="select2 select2-container">' +
28426        '<span class="selection"></span>' +
28427        '<span class="dropdown-wrapper" aria-hidden="true"></span>' +
28428      '</span>'
28429    );
28430
28431    $container.attr('dir', this.options.get('dir'));
28432
28433    this.$container = $container;
28434
28435    this.$container[0].classList
28436      .add('select2-container--' + this.options.get('theme'));
28437
28438    Utils.StoreData($container[0], 'element', this.$element);
28439
28440    return $container;
28441  };
28442
28443  return Select2;
28444});
28445
28446S2.define('jquery-mousewheel',[
28447  'jquery'
28448], function ($) {
28449  // Used to shim jQuery.mousewheel for non-full builds.
28450  return $;
28451});
28452
28453S2.define('jquery.select2',[
28454  'jquery',
28455  'jquery-mousewheel',
28456
28457  './select2/core',
28458  './select2/defaults',
28459  './select2/utils'
28460], function ($, _, Select2, Defaults, Utils) {
28461  if ($.fn.select2 == null) {
28462    // All methods that should return the element
28463    var thisMethods = ['open', 'close', 'destroy'];
28464
28465    $.fn.select2 = function (options) {
28466      options = options || {};
28467
28468      if (typeof options === 'object') {
28469        this.each(function () {
28470          var instanceOptions = $.extend(true, {}, options);
28471
28472          var instance = new Select2($(this), instanceOptions);
28473        });
28474
28475        return this;
28476      } else if (typeof options === 'string') {
28477        var ret;
28478        var args = Array.prototype.slice.call(arguments, 1);
28479
28480        this.each(function () {
28481          var instance = Utils.GetData(this, 'select2');
28482
28483          if (instance == null && window.console && console.error) {
28484            console.error(
28485              'The select2(\'' + options + '\') method was called on an ' +
28486              'element that is not using Select2.'
28487            );
28488          }
28489
28490          ret = instance[options].apply(instance, args);
28491        });
28492
28493        // Check if we should be returning `this`
28494        if (thisMethods.indexOf(options) > -1) {
28495          return this;
28496        }
28497
28498        return ret;
28499      } else {
28500        throw new Error('Invalid arguments for Select2: ' + options);
28501      }
28502    };
28503  }
28504
28505  if ($.fn.select2.defaults == null) {
28506    $.fn.select2.defaults = Defaults;
28507  }
28508
28509  return Select2;
28510});
28511
28512  // Return the AMD loader configuration so it can be used outside of this file
28513  return {
28514    define: S2.define,
28515    require: S2.require
28516  };
28517}());
28518
28519  // Autoload the jQuery bindings
28520  // We know that all of the modules exist above this, so we're safe
28521  var select2 = S2.require('jquery.select2');
28522
28523  // Hold the AMD module references on the jQuery function that was just loaded
28524  // This allows Select2 to use the internal loader outside of this file, such
28525  // as in the language files.
28526  jQuery.fn.select2.amd = S2;
28527
28528  // Return the Select2 instance for anyone who is importing it.
28529  return select2;
28530}));
28531
28532/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2)))
28533
28534/***/ }),
28535/* 150 */
28536/***/ (function(module, exports, __webpack_require__) {
28537
28538var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
28539 * jQuery UI Widget 1.13.0
28540 * http://jqueryui.com
28541 *
28542 * Copyright jQuery Foundation and other contributors
28543 * Released under the MIT license.
28544 * http://jquery.org/license
28545 */
28546
28547//>>label: Widget
28548//>>group: Core
28549//>>description: Provides a factory for creating stateful widgets with a common API.
28550//>>docs: http://api.jqueryui.com/jQuery.widget/
28551//>>demos: http://jqueryui.com/widget/
28552
28553( function( factory ) {
28554	"use strict";
28555
28556	if ( true ) {
28557
28558		// AMD. Register as an anonymous module.
28559		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2), __webpack_require__(5) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
28560				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
28561				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
vendor: 6,174 bytes, lines 28562-28770
28562				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
28563	} else {
28564
28565		// Browser globals
28566		factory( jQuery );
28567	}
28568} )( function( $ ) {
28569"use strict";
28570
28571var widgetUuid = 0;
28572var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
28573var widgetSlice = Array.prototype.slice;
28574
28575$.cleanData = ( function( orig ) {
28576	return function( elems ) {
28577		var events, elem, i;
28578		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
28579
28580			// Only trigger remove when necessary to save time
28581			events = $._data( elem, "events" );
28582			if ( events && events.remove ) {
28583				$( elem ).triggerHandler( "remove" );
28584			}
28585		}
28586		orig( elems );
28587	};
28588} )( $.cleanData );
28589
28590$.widget = function( name, base, prototype ) {
28591	var existingConstructor, constructor, basePrototype;
28592
28593	// ProxiedPrototype allows the provided prototype to remain unmodified
28594	// so that it can be used as a mixin for multiple widgets (#8876)
28595	var proxiedPrototype = {};
28596
28597	var namespace = name.split( "." )[ 0 ];
28598	name = name.split( "." )[ 1 ];
28599	var fullName = namespace + "-" + name;
28600
28601	if ( !prototype ) {
28602		prototype = base;
28603		base = $.Widget;
28604	}
28605
28606	if ( Array.isArray( prototype ) ) {
28607		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
28608	}
28609
28610	// Create selector for plugin
28611	$.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
28612		return !!$.data( elem, fullName );
28613	};
28614
28615	$[ namespace ] = $[ namespace ] || {};
28616	existingConstructor = $[ namespace ][ name ];
28617	constructor = $[ namespace ][ name ] = function( options, element ) {
28618
28619		// Allow instantiation without "new" keyword
28620		if ( !this._createWidget ) {
28621			return new constructor( options, element );
28622		}
28623
28624		// Allow instantiation without initializing for simple inheritance
28625		// must use "new" keyword (the code above always passes args)
28626		if ( arguments.length ) {
28627			this._createWidget( options, element );
28628		}
28629	};
28630
28631	// Extend with the existing constructor to carry over any static properties
28632	$.extend( constructor, existingConstructor, {
28633		version: prototype.version,
28634
28635		// Copy the object used to create the prototype in case we need to
28636		// redefine the widget later
28637		_proto: $.extend( {}, prototype ),
28638
28639		// Track widgets that inherit from this widget in case this widget is
28640		// redefined after a widget inherits from it
28641		_childConstructors: []
28642	} );
28643
28644	basePrototype = new base();
28645
28646	// We need to make the options hash a property directly on the new instance
28647	// otherwise we'll modify the options hash on the prototype that we're
28648	// inheriting from
28649	basePrototype.options = $.widget.extend( {}, basePrototype.options );
28650	$.each( prototype, function( prop, value ) {
28651		if ( typeof value !== "function" ) {
28652			proxiedPrototype[ prop ] = value;
28653			return;
28654		}
28655		proxiedPrototype[ prop ] = ( function() {
28656			function _super() {
28657				return base.prototype[ prop ].apply( this, arguments );
28658			}
28659
28660			function _superApply( args ) {
28661				return base.prototype[ prop ].apply( this, args );
28662			}
28663
28664			return function() {
28665				var __super = this._super;
28666				var __superApply = this._superApply;
28667				var returnValue;
28668
28669				this._super = _super;
28670				this._superApply = _superApply;
28671
28672				returnValue = value.apply( this, arguments );
28673
28674				this._super = __super;
28675				this._superApply = __superApply;
28676
28677				return returnValue;
28678			};
28679		} )();
28680	} );
28681	constructor.prototype = $.widget.extend( basePrototype, {
28682
28683		// TODO: remove support for widgetEventPrefix
28684		// always use the name + a colon as the prefix, e.g., draggable:start
28685		// don't prefix for widgets that aren't DOM-based
28686		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
28687	}, proxiedPrototype, {
28688		constructor: constructor,
28689		namespace: namespace,
28690		widgetName: name,
28691		widgetFullName: fullName
28692	} );
28693
28694	// If this widget is being redefined then we need to find all widgets that
28695	// are inheriting from it and redefine all of them so that they inherit from
28696	// the new version of this widget. We're essentially trying to replace one
28697	// level in the prototype chain.
28698	if ( existingConstructor ) {
28699		$.each( existingConstructor._childConstructors, function( i, child ) {
28700			var childPrototype = child.prototype;
28701
28702			// Redefine the child widget using the same prototype that was
28703			// originally used, but inherit from the new version of the base
28704			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
28705				child._proto );
28706		} );
28707
28708		// Remove the list of existing child constructors from the old constructor
28709		// so the old child constructors can be garbage collected
28710		delete existingConstructor._childConstructors;
28711	} else {
28712		base._childConstructors.push( constructor );
28713	}
28714
28715	$.widget.bridge( name, constructor );
28716
28717	return constructor;
28718};
28719
28720$.widget.extend = function( target ) {
28721	var input = widgetSlice.call( arguments, 1 );
28722	var inputIndex = 0;
28723	var inputLength = input.length;
28724	var key;
28725	var value;
28726
28727	for ( ; inputIndex < inputLength; inputIndex++ ) {
28728		for ( key in input[ inputIndex ] ) {
28729			value = input[ inputIndex ][ key ];
28730			if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) {
28731
28732				// Clone objects
28733				if ( $.isPlainObject( value ) ) {
28734					target[ key ] = $.isPlainObject( target[ key ] ) ?
28735						$.widget.extend( {}, target[ key ], value ) :
28736
28737						// Don't extend strings, arrays, etc. with objects
28738						$.widget.extend( {}, value );
28739
28740				// Copy everything else by reference
28741				} else {
28742					target[ key ] = value;
28743				}
28744			}
28745		}
28746	}
28747	return target;
28748};
28749
28750$.widget.bridge = function( name, object ) {
28751	var fullName = object.prototype.widgetFullName || name;
28752	$.fn[ name ] = function( options ) {
28753		var isMethodCall = typeof options === "string";
28754		var args = widgetSlice.call( arguments, 1 );
28755		var returnValue = this;
28756
28757		if ( isMethodCall ) {
28758
28759			// If this is an empty collection, we need to have the instance method
28760			// return undefined instead of the jQuery instance
28761			if ( !this.length && options === "instance" ) {
28762				returnValue = undefined;
28763			} else {
28764				this.each( function() {
28765					var methodValue;
28766					var instance = $.data( this, fullName );
28767
28768					if ( options === "instance" ) {
28769						returnValue = instance;
28770						return false;
vendor: 13,302 bytes, lines 28771-29276
28771					}
28772
28773					if ( !instance ) {
28774						return $.error( "cannot call methods on " + name +
28775							" prior to initialization; " +
28776							"attempted to call method '" + options + "'" );
28777					}
28778
28779					if ( typeof instance[ options ] !== "function" ||
28780						options.charAt( 0 ) === "_" ) {
28781						return $.error( "no such method '" + options + "' for " + name +
28782							" widget instance" );
28783					}
28784
28785					methodValue = instance[ options ].apply( instance, args );
28786
28787					if ( methodValue !== instance && methodValue !== undefined ) {
28788						returnValue = methodValue && methodValue.jquery ?
28789							returnValue.pushStack( methodValue.get() ) :
28790							methodValue;
28791						return false;
28792					}
28793				} );
28794			}
28795		} else {
28796
28797			// Allow multiple hashes to be passed on init
28798			if ( args.length ) {
28799				options = $.widget.extend.apply( null, [ options ].concat( args ) );
28800			}
28801
28802			this.each( function() {
28803				var instance = $.data( this, fullName );
28804				if ( instance ) {
28805					instance.option( options || {} );
28806					if ( instance._init ) {
28807						instance._init();
28808					}
28809				} else {
28810					$.data( this, fullName, new object( options, this ) );
28811				}
28812			} );
28813		}
28814
28815		return returnValue;
28816	};
28817};
28818
28819$.Widget = function( /* options, element */ ) {};
28820$.Widget._childConstructors = [];
28821
28822$.Widget.prototype = {
28823	widgetName: "widget",
28824	widgetEventPrefix: "",
28825	defaultElement: "<div>",
28826
28827	options: {
28828		classes: {},
28829		disabled: false,
28830
28831		// Callbacks
28832		create: null
28833	},
28834
28835	_createWidget: function( options, element ) {
28836		element = $( element || this.defaultElement || this )[ 0 ];
28837		this.element = $( element );
28838		this.uuid = widgetUuid++;
28839		this.eventNamespace = "." + this.widgetName + this.uuid;
28840
28841		this.bindings = $();
28842		this.hoverable = $();
28843		this.focusable = $();
28844		this.classesElementLookup = {};
28845
28846		if ( element !== this ) {
28847			$.data( element, this.widgetFullName, this );
28848			this._on( true, this.element, {
28849				remove: function( event ) {
28850					if ( event.target === element ) {
28851						this.destroy();
28852					}
28853				}
28854			} );
28855			this.document = $( element.style ?
28856
28857				// Element within the document
28858				element.ownerDocument :
28859
28860				// Element is window or document
28861				element.document || element );
28862			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
28863		}
28864
28865		this.options = $.widget.extend( {},
28866			this.options,
28867			this._getCreateOptions(),
28868			options );
28869
28870		this._create();
28871
28872		if ( this.options.disabled ) {
28873			this._setOptionDisabled( this.options.disabled );
28874		}
28875
28876		this._trigger( "create", null, this._getCreateEventData() );
28877		this._init();
28878	},
28879
28880	_getCreateOptions: function() {
28881		return {};
28882	},
28883
28884	_getCreateEventData: $.noop,
28885
28886	_create: $.noop,
28887
28888	_init: $.noop,
28889
28890	destroy: function() {
28891		var that = this;
28892
28893		this._destroy();
28894		$.each( this.classesElementLookup, function( key, value ) {
28895			that._removeClass( value, key );
28896		} );
28897
28898		// We can probably remove the unbind calls in 2.0
28899		// all event bindings should go through this._on()
28900		this.element
28901			.off( this.eventNamespace )
28902			.removeData( this.widgetFullName );
28903		this.widget()
28904			.off( this.eventNamespace )
28905			.removeAttr( "aria-disabled" );
28906
28907		// Clean up events and states
28908		this.bindings.off( this.eventNamespace );
28909	},
28910
28911	_destroy: $.noop,
28912
28913	widget: function() {
28914		return this.element;
28915	},
28916
28917	option: function( key, value ) {
28918		var options = key;
28919		var parts;
28920		var curOption;
28921		var i;
28922
28923		if ( arguments.length === 0 ) {
28924
28925			// Don't return a reference to the internal hash
28926			return $.widget.extend( {}, this.options );
28927		}
28928
28929		if ( typeof key === "string" ) {
28930
28931			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
28932			options = {};
28933			parts = key.split( "." );
28934			key = parts.shift();
28935			if ( parts.length ) {
28936				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
28937				for ( i = 0; i < parts.length - 1; i++ ) {
28938					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
28939					curOption = curOption[ parts[ i ] ];
28940				}
28941				key = parts.pop();
28942				if ( arguments.length === 1 ) {
28943					return curOption[ key ] === undefined ? null : curOption[ key ];
28944				}
28945				curOption[ key ] = value;
28946			} else {
28947				if ( arguments.length === 1 ) {
28948					return this.options[ key ] === undefined ? null : this.options[ key ];
28949				}
28950				options[ key ] = value;
28951			}
28952		}
28953
28954		this._setOptions( options );
28955
28956		return this;
28957	},
28958
28959	_setOptions: function( options ) {
28960		var key;
28961
28962		for ( key in options ) {
28963			this._setOption( key, options[ key ] );
28964		}
28965
28966		return this;
28967	},
28968
28969	_setOption: function( key, value ) {
28970		if ( key === "classes" ) {
28971			this._setOptionClasses( value );
28972		}
28973
28974		this.options[ key ] = value;
28975
28976		if ( key === "disabled" ) {
28977			this._setOptionDisabled( value );
28978		}
28979
28980		return this;
28981	},
28982
28983	_setOptionClasses: function( value ) {
28984		var classKey, elements, currentElements;
28985
28986		for ( classKey in value ) {
28987			currentElements = this.classesElementLookup[ classKey ];
28988			if ( value[ classKey ] === this.options.classes[ classKey ] ||
28989					!currentElements ||
28990					!currentElements.length ) {
28991				continue;
28992			}
28993
28994			// We are doing this to create a new jQuery object because the _removeClass() call
28995			// on the next line is going to destroy the reference to the current elements being
28996			// tracked. We need to save a copy of this collection so that we can add the new classes
28997			// below.
28998			elements = $( currentElements.get() );
28999			this._removeClass( currentElements, classKey );
29000
29001			// We don't use _addClass() here, because that uses this.options.classes
29002			// for generating the string of classes. We want to use the value passed in from
29003			// _setOption(), this is the new value of the classes option which was passed to
29004			// _setOption(). We pass this value directly to _classes().
29005			elements.addClass( this._classes( {
29006				element: elements,
29007				keys: classKey,
29008				classes: value,
29009				add: true
29010			} ) );
29011		}
29012	},
29013
29014	_setOptionDisabled: function( value ) {
29015		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
29016
29017		// If the widget is becoming disabled, then nothing is interactive
29018		if ( value ) {
29019			this._removeClass( this.hoverable, null, "ui-state-hover" );
29020			this._removeClass( this.focusable, null, "ui-state-focus" );
29021		}
29022	},
29023
29024	enable: function() {
29025		return this._setOptions( { disabled: false } );
29026	},
29027
29028	disable: function() {
29029		return this._setOptions( { disabled: true } );
29030	},
29031
29032	_classes: function( options ) {
29033		var full = [];
29034		var that = this;
29035
29036		options = $.extend( {
29037			element: this.element,
29038			classes: this.options.classes || {}
29039		}, options );
29040
29041		function bindRemoveEvent() {
29042			options.element.each( function( _, element ) {
29043				var isTracked = $.map( that.classesElementLookup, function( elements ) {
29044					return elements;
29045				} )
29046					.some( function( elements ) {
29047						return elements.is( element );
29048					} );
29049
29050				if ( !isTracked ) {
29051					that._on( $( element ), {
29052						remove: "_untrackClassesElement"
29053					} );
29054				}
29055			} );
29056		}
29057
29058		function processClassString( classes, checkOption ) {
29059			var current, i;
29060			for ( i = 0; i < classes.length; i++ ) {
29061				current = that.classesElementLookup[ classes[ i ] ] || $();
29062				if ( options.add ) {
29063					bindRemoveEvent();
29064					current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) );
29065				} else {
29066					current = $( current.not( options.element ).get() );
29067				}
29068				that.classesElementLookup[ classes[ i ] ] = current;
29069				full.push( classes[ i ] );
29070				if ( checkOption && options.classes[ classes[ i ] ] ) {
29071					full.push( options.classes[ classes[ i ] ] );
29072				}
29073			}
29074		}
29075
29076		if ( options.keys ) {
29077			processClassString( options.keys.match( /\S+/g ) || [], true );
29078		}
29079		if ( options.extra ) {
29080			processClassString( options.extra.match( /\S+/g ) || [] );
29081		}
29082
29083		return full.join( " " );
29084	},
29085
29086	_untrackClassesElement: function( event ) {
29087		var that = this;
29088		$.each( that.classesElementLookup, function( key, value ) {
29089			if ( $.inArray( event.target, value ) !== -1 ) {
29090				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
29091			}
29092		} );
29093
29094		this._off( $( event.target ) );
29095	},
29096
29097	_removeClass: function( element, keys, extra ) {
29098		return this._toggleClass( element, keys, extra, false );
29099	},
29100
29101	_addClass: function( element, keys, extra ) {
29102		return this._toggleClass( element, keys, extra, true );
29103	},
29104
29105	_toggleClass: function( element, keys, extra, add ) {
29106		add = ( typeof add === "boolean" ) ? add : extra;
29107		var shift = ( typeof element === "string" || element === null ),
29108			options = {
29109				extra: shift ? keys : extra,
29110				keys: shift ? element : keys,
29111				element: shift ? this.element : element,
29112				add: add
29113			};
29114		options.element.toggleClass( this._classes( options ), add );
29115		return this;
29116	},
29117
29118	_on: function( suppressDisabledCheck, element, handlers ) {
29119		var delegateElement;
29120		var instance = this;
29121
29122		// No suppressDisabledCheck flag, shuffle arguments
29123		if ( typeof suppressDisabledCheck !== "boolean" ) {
29124			handlers = element;
29125			element = suppressDisabledCheck;
29126			suppressDisabledCheck = false;
29127		}
29128
29129		// No element argument, shuffle and use this.element
29130		if ( !handlers ) {
29131			handlers = element;
29132			element = this.element;
29133			delegateElement = this.widget();
29134		} else {
29135			element = delegateElement = $( element );
29136			this.bindings = this.bindings.add( element );
29137		}
29138
29139		$.each( handlers, function( event, handler ) {
29140			function handlerProxy() {
29141
29142				// Allow widgets to customize the disabled handling
29143				// - disabled as an array instead of boolean
29144				// - disabled class as method for disabling individual parts
29145				if ( !suppressDisabledCheck &&
29146						( instance.options.disabled === true ||
29147						$( this ).hasClass( "ui-state-disabled" ) ) ) {
29148					return;
29149				}
29150				return ( typeof handler === "string" ? instance[ handler ] : handler )
29151					.apply( instance, arguments );
29152			}
29153
29154			// Copy the guid so direct unbinding works
29155			if ( typeof handler !== "string" ) {
29156				handlerProxy.guid = handler.guid =
29157					handler.guid || handlerProxy.guid || $.guid++;
29158			}
29159
29160			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
29161			var eventName = match[ 1 ] + instance.eventNamespace;
29162			var selector = match[ 2 ];
29163
29164			if ( selector ) {
29165				delegateElement.on( eventName, selector, handlerProxy );
29166			} else {
29167				element.on( eventName, handlerProxy );
29168			}
29169		} );
29170	},
29171
29172	_off: function( element, eventName ) {
29173		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
29174			this.eventNamespace;
29175		element.off( eventName );
29176
29177		// Clear the stack to avoid memory leaks (#10056)
29178		this.bindings = $( this.bindings.not( element ).get() );
29179		this.focusable = $( this.focusable.not( element ).get() );
29180		this.hoverable = $( this.hoverable.not( element ).get() );
29181	},
29182
29183	_delay: function( handler, delay ) {
29184		function handlerProxy() {
29185			return ( typeof handler === "string" ? instance[ handler ] : handler )
29186				.apply( instance, arguments );
29187		}
29188		var instance = this;
29189		return setTimeout( handlerProxy, delay || 0 );
29190	},
29191
29192	_hoverable: function( element ) {
29193		this.hoverable = this.hoverable.add( element );
29194		this._on( element, {
29195			mouseenter: function( event ) {
29196				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
29197			},
29198			mouseleave: function( event ) {
29199				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
29200			}
29201		} );
29202	},
29203
29204	_focusable: function( element ) {
29205		this.focusable = this.focusable.add( element );
29206		this._on( element, {
29207			focusin: function( event ) {
29208				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
29209			},
29210			focusout: function( event ) {
29211				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
29212			}
29213		} );
29214	},
29215
29216	_trigger: function( type, event, data ) {
29217		var prop, orig;
29218		var callback = this.options[ type ];
29219
29220		data = data || {};
29221		event = $.Event( event );
29222		event.type = ( type === this.widgetEventPrefix ?
29223			type :
29224			this.widgetEventPrefix + type ).toLowerCase();
29225
29226		// The original event may come from any element
29227		// so we need to reset the target on the new event
29228		event.target = this.element[ 0 ];
29229
29230		// Copy original event properties over to the new event
29231		orig = event.originalEvent;
29232		if ( orig ) {
29233			for ( prop in orig ) {
29234				if ( !( prop in event ) ) {
29235					event[ prop ] = orig[ prop ];
29236				}
29237			}
29238		}
29239
29240		this.element.trigger( event, data );
29241		return !( typeof callback === "function" &&
29242			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
29243			event.isDefaultPrevented() );
29244	}
29245};
29246
29247$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
29248	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
29249		if ( typeof options === "string" ) {
29250			options = { effect: options };
29251		}
29252
29253		var hasOptions;
29254		var effectName = !options ?
29255			method :
29256			options === true || typeof options === "number" ?
29257				defaultEffect :
29258				options.effect || defaultEffect;
29259
29260		options = options || {};
29261		if ( typeof options === "number" ) {
29262			options = { duration: options };
29263		} else if ( options === true ) {
29264			options = {};
29265		}
29266
29267		hasOptions = !$.isEmptyObject( options );
29268		options.complete = callback;
29269
29270		if ( options.delay ) {
29271			element.delay( options.delay );
29272		}
29273
29274		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
29275			element[ method ]( options );
29276		} else if ( effectName !== method && element[ effectName ] ) {
29277			element[ effectName ]( options.duration, options.easing, callback );
29278		} else {
29279			element.queue( function( next ) {
29280				$( this )[ method ]();
29281				if ( callback ) {
29282					callback.call( element[ 0 ] );
29283				}
29284				next();
29285			} );
29286		}
29287	};
29288} );
29289
29290return $.widget;
29291
29292} );
29293
29294
29295/***/ }),
29296/* 151 */
29297/***/ (function(module, exports, __webpack_require__) {
29298
29299__webpack_require__(152);
29300module.exports = __webpack_require__(275);
29301
29302
29303/***/ }),
29304/* 152 */
29305/***/ (function(module, __webpack_exports__, __webpack_require__) {
29306
29307"use strict";
29308Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
29309/* WEBPACK VAR INJECTION */(function(jQuery) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery__ = __webpack_require__(2);
29310/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_jquery__);
29311/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_Router__ = __webpack_require__(153);
29312/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__routes_common__ = __webpack_require__(155);
29313/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__routes_build__ = __webpack_require__(252);
29314/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__routes_program__ = __webpack_require__(253);
29315/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__routes_single__ = __webpack_require__(254);
29316/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__routes_tour__ = __webpack_require__(273);
29317/* eslint-disable */
29318// import external dependencies
29319
29320
29321// Import everything from autoload
29322//;
29323
29324// import local dependencies
29325
29326
29327
29328
29329
29330
29331
29332var csv = __webpack_require__(274);
29333
29334/** Populate Router instance with DOM routes */
29335var routes = new __WEBPACK_IMPORTED_MODULE_1__util_Router__["a" /* default */]({
29336  // All pages
29337  common: __WEBPACK_IMPORTED_MODULE_2__routes_common__["a" /* default */],
29338  // Build page
29339  buildPage: __WEBPACK_IMPORTED_MODULE_3__routes_build__["a" /* default */],
29340  programPage: __WEBPACK_IMPORTED_MODULE_4__routes_program__["a" /* default */],
29341  // Single Page
29342  single: __WEBPACK_IMPORTED_MODULE_5__routes_single__["a" /* default */],
29343  // Tour Page
29344  tourPage: __WEBPACK_IMPORTED_MODULE_6__routes_tour__["a" /* default */],
29345});
29346
29347// Load Events
29348jQuery(document).ready(function () { return routes.loadEvents(); });
29349
29350
29351//Header Setup
29352(function (){
29353  var addPaddingForHero = function () {
29354    var setTopPadding = function () {
29355      var headerTopHeight =  document.querySelector('.top-header__inner').getBoundingClientRect().height;
29356      var headerBottomHeight =  document.querySelector('.header__inner').getBoundingClientRect().height;
29357      document.querySelector('main.main').style.marginTop = (headerTopHeight + headerBottomHeight) + "px";
29358
29359    }
29360    setTopPadding();
29361    window.addEventListener('resize', function () {
29362      setTimeout(setTopPadding, 250)
29363    })
29364  }
29365  window.addEventListener('DOMContentLoaded', function () {
29366    addPaddingForHero()
29367  });
29368})();
29369
29370
29371/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(2)))
29372
29373/***/ }),
29374/* 153 */
29375/***/ (function(module, __webpack_exports__, __webpack_require__) {
29376
29377"use strict";
29378/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__camelCase__ = __webpack_require__(154);
29379
29380
29381/**
29382 * DOM-based Routing
29383 *
29384 * Based on {@link http://goo.gl/EUTi53|Markup-based Unobtrusive Comprehensive DOM-ready Execution} by Paul Irish
29385 *
29386 * The routing fires all common scripts, followed by the page specific scripts.
29387 * Add additional events for more control over timing e.g. a finalize event
29388 */
29389var Router = function Router(routes) {
29390  this.routes = routes;
29391};
29392
29393/**
29394 * Fire Router events
29395 * @param {string} route DOM-based route derived from body classes (`<body class="...">`)
29396 * @param {string} [event] Events on the route. By default, `init` and `finalize` events are called.
29397 * @param {string} [arg] Any custom argument to be passed to the event.
29398 */
29399Router.prototype.fire = function fire (route, event, arg) {
29400    if ( event === void 0 ) event = 'init';
29401
29402  document.dispatchEvent(new CustomEvent('routed', {
29403    bubbles: true,
29404    detail: {
29405      route: route,
29406      fn: event,
29407    },
29408  }));
29409
29410  var fire = route !== '' && this.routes[route] && typeof this.routes[route][event] === 'function';
29411  if (fire) {
29412    this.routes[route][event](arg);
29413  }
29414};
29415
29416/**
29417 * Automatically load and fire Router events
29418 *
29419 * Events are fired in the following order:
29420 ** common init
29421 ** page-specific init
29422 ** page-specific finalize
29423 ** common finalize
29424 */
29425Router.prototype.loadEvents = function loadEvents () {
29426    var this$1 = this;
29427
29428  // Fire common init JS
29429  this.fire('common');
29430
29431  // Fire page-specific init JS, and then finalize JS
29432  document.body.className
29433    .toLowerCase()
29434    .replace(/-/g, '_')
29435    .split(/\s+/)
29436    .map(__WEBPACK_IMPORTED_MODULE_0__camelCase__["a" /* default */])
29437    .forEach(function (className) {
29438      this$1.fire(className);
29439      this$1.fire(className, 'finalize');
29440    });
29441
29442  // Fire common finalize JS
29443  this.fire('common', 'finalize');
29444};
29445
29446/* harmony default export */ __webpack_exports__["a"] = (Router);
29447
29448
29449/***/ }),
29450/* 154 */
29451/***/ (function(module, __webpack_exports__, __webpack_require__) {
29452
29453"use strict";
29454/**
29455 * the most terrible camelizer on the internet, guaranteed!
29456 * @param {string} str String that isn't camel-case, e.g., CAMeL_CaSEiS-harD
29457 * @return {string} String converted to camel-case, e.g., camelCaseIsHard
29458 */
29459/* harmony default export */ __webpack_exports__["a"] = (function (str) { return ("" + (str.charAt(0).toLowerCase()) + (str.replace(/[\W_]/g, '|').split('|')
29460  .map(function (part) { return ("" + (part.charAt(0).toUpperCase()) + (part.slice(1))); })
29461  .join('')
29462  .slice(1))); });;
29463
29464
29465/***/ }),
29466/* 155 */
29467/***/ (function(module, __webpack_exports__, __webpack_require__) {
29468
29469"use strict";
29470/* WEBPACK VAR INJECTION */(function($, jQuery) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_masonry_layout__ = __webpack_require__(7);
29471/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_masonry_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_masonry_layout__);
29472/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_moment_dist_moment__ = __webpack_require__(0);
29473/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_jquery_ui_ui_widgets_datepicker__ = __webpack_require__(162);
29474/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_jquery_ui_ui_widgets_datepicker___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_jquery_ui_ui_widgets_datepicker__);
29475/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_jquery_maskedinput_src_jquery_maskedinput__ = __webpack_require__(164);
29476/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_jquery_maskedinput_src_jquery_maskedinput___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_jquery_maskedinput_src_jquery_maskedinput__);
29477/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__fancyapps_fancybox_dist_jquery_fancybox__ = __webpack_require__(165);
29478/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__fancyapps_fancybox_dist_jquery_fancybox___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4__fancyapps_fancybox_dist_jquery_fancybox__);
29479/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_swiper_bundle__ = __webpack_require__(6);
29480/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_imagesloaded_imagesloaded__ = __webpack_require__(251);
29481/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_imagesloaded_imagesloaded___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_imagesloaded_imagesloaded__);
29482
29483
29484
29485
29486
29487
29488
29489
29490/* harmony default export */ __webpack_exports__["a"] = ({
29491  init: function init() {
29492    // JavaScript to be fired on all pages
29493  },
29494  finalize: function finalize() {
29495
29496    /**
29497     * Download Quote
29498     */
29499    if ($('.download_course').length > 0) {
29500      $(document).on('click', '.download_course', function (e) {
29501        e.preventDefault();
29502        //	Get width and height for IE.
29503        var WIDTH, HEIGHT, LEFT, TOP;
29504        var NAME='print_preview';
29505        var SCROLL='yes';
29506        if (screen.height) {
29507          WIDTH  = screen.width/2;
29508          HEIGHT = screen.height/2;
29509          LEFT = (screen.width - WIDTH) / 2;
29510          TOP = (screen.height - HEIGHT) / 2;
29511        } else {
29512           WIDTH  = screen.availWidth/2;
29513           HEIGHT = screen.availHeight/2;
29514          LEFT = (screen.availWidth - WIDTH) / 2;
29515          TOP = (screen.availHeight - HEIGHT) / 2;
29516        }
29517        console.log(e, e.target)
29518        var program = e.currentTarget.dataset.programid;
29519        var catalog = e.currentTarget.dataset.catalogid;
29520        var URL = 'https://catalog.nec.edu/preview_degree_planner.php?catoid='+catalog+'&poid='+program+'&returnto=1049&print';
29521        console.log(URL);
29522        var popupWindow = window.open(URL,NAME,'height='+HEIGHT+',width='+WIDTH+',resizable=yes,scrollbars='+SCROLL+',menubar=no,toolbar=no,personalbar=no,statusbar=no,locationbar=no,screenX='+LEFT+',screenY='+TOP+',left='+LEFT+',top='+TOP);
29523        if(popupWindow != null) {
29524          popupWindow.focus();
29525        }
29526      })}
29527
29528    /**
29529     * Swiper Quote
29530     */
29531    if ($('.alert_close').length > 0) {
29532      $(document).on('click', '.alert_close', function () {
29533        $('.alert_bar').remove()
29534        $('.with_alert').removeClass('with_alert');
29535      });
29536    }
29537
29538
29539    /**
29540     * Swiper Quote
29541     */
29542    if ($('.quote_slider').length > 0) {
29543      new __WEBPACK_IMPORTED_MODULE_5_swiper_bundle__["a" /* default */]('.quote_slider .swiper-container', {
29544        autoHeight: true, //enable auto height
29545        slidesPerView   : 1,
29546        spaceBetween    : 0,
29547        loop            : true,
29548        effect          :'fade',
29549        speed           : 800,
29550        pagination      : {
29551          el            : '.swiper-pagination',
29552          clickable     : true,
29553          type          : 'bullets',
29554        },
29555        navigation: {
29556          nextEl        : '.swiper-button-next',
29557          prevEl        : '.swiper-button-prev',
29558        },
29559      });
29560    }
29561
29562    /**
29563     * Swiper Dynamic Content
29564     */
29565    if ($('.dynamic__slider').length > 0) {
29566      new __WEBPACK_IMPORTED_MODULE_5_swiper_bundle__["a" /* default */]('.dynamic__slider .swiper-container', {
29567        autoHeight: true, //enable auto height
29568        slidesPerView : 1,
29569        spaceBetween  : 0,
29570        loop          : true,
29571        effect          :'fade',
29572        speed           : 800,
29573        pagination: {
29574          el          : '.dynamic__slider .swiper-pagination',
29575          clickable   : true,
29576          type        : 'bullets',
29577        },
29578        navigation: {
29579          nextEl      : '.dynamic__slider .swiper-button-next',
29580          prevEl      : '.dynamic__slider .swiper-button-prev',
29581        },
29582      });
29583    }
29584
29585
29586    /**
29587     * Fancybox
29588     * @fancybox
29589     */
29590    $('[data-fancybox]').fancybox({
29591      // Options will go here
29592    });
29593
29594    /**
29595     * Header
29596     * @type {{init: init}}
29597     */
29598    var Header = function () {
29599
29600      /**
29601       * Install
29602       * @param data
29603       * @constructor
29604       */
29605      var Install = function () {
29606
29607
29608        /**
29609         * Mobile Menu
29610         * @click
29611         * Slinky Menu
29612         *
29613         */
29614        $(document).on('click', '#headerSlinky .menu__click', function (e) {
29615
29616          var $li = $(this).parent();
29617
29618          if ($li.hasClass('active_menu')) {
29619            $li.removeClass('active_menu');
29620          } else {
29621            $li.addClass('active_menu');
29622          }
29623
29624          e.preventDefault();
29625        });
29626
29627        if ($('#headerSlinky').length) {
29628          $('#headerSlinky > li').each(function () {
29629            if ($(this).find('.sub-menu').length) {
29630              $(this).append('<div class="menu__click"></div>');
29631            }
29632          });
29633        }
29634
29635        /**
29636         * Mobile Menu
29637         * @click
29638         * Slinky Menu
29639         */
29640        $(document).on('click', '#headerSlinky > li.header__menu__item--submenu.active .menu__click', function (e) {
29641
29642          $(this).parent().removeClass('active');
29643          $(this).parent().parent().parent().find('li.hide').removeClass('hide');
29644          $('.header__mob .hideSlinky').removeClass('hide');
29645
29646          e.preventDefault();
29647        });
29648
29649        /**
29650         * Menu Mobile Header
29651         * @click
29652         * Small Menu Accordion
29653         */
29654        $(document).on('click', '.header__mob .top-header__menu__item--submenu > a', function (e) {
29655
29656          $(this).parent().toggleClass('active');
29657          e.preventDefault();
29658
29659        });
29660
29661        /**
29662         * Menu Mobile Header
29663         * @click
29664         */
29665        $(document).on('click', '#header__burger', function (e) {
29666
29667          $('body')
29668            .toggleClass('menu__active')
29669            .toggleClass('no-scroll');
29670
29671          e.preventDefault();
29672        });
29673
29674      }
29675
29676      /**
29677       * MegaMenu
29678       * @constructor
29679       */
29680      var Megamenu = function () {
29681
29682        var visible_menu = 0,
29683          // speed_menu = 300,
29684          timer_menu;
29685        if ($(window).width() > 1200) {
29686
29687          /**
29688           * header__menu__item
29689           * @hover
29690           */
29691          $('.header__menu__item--submenu').hover(function () {
29692            // var _speed_menu = $(this).hasClass('header__menu__item--submenu') && $('.megamenu .megamenu__item:visible').length ? 0 : speed_menu;
29693
29694            visible_menu = 1;
29695            clearTimeout(timer_menu);
29696            // $('.megamenu__item').delay(0).slideUp(_speed_menu);
29697            $('.megamenu__item').removeClass('megamenu__item--active');
29698
29699            var $menu = $('#megamenu-' + $(this).attr('id')),
29700              $this = $(this);
29701
29702            $menu.addClass('megamenu__item--active');
29703
29704            // $menu.stop(true).delay(_speed_menu).slideDown(_speed_menu);
29705            $('.header__menu').find('.active').removeClass('active');
29706            $this.addClass('active');
29707            $('.megamenu').addClass('megamenu--active');
29708
29709          }, function () {
29710
29711            timer_menu = setTimeout(function () {
29712              if (visible_menu === 1) {
29713                visible_menu = 0;
29714                // $('.megamenu__item').stop(true).delay(speed_menu).slideUp(speed_menu);
29715                $('.megamenu__item').removeClass('megamenu__item--active');
29716                $('.header__menu').find('.active').removeClass('active');
29717                $('.megamenu').removeClass('megamenu--active');
29718              }
29719
29720            }, 0);
29721
29722          });
29723
29724          /**
29725           * megamenu__item
29726           * @hover
29727           */
29728          $('.megamenu__item').hover(function () {
29729
29730            visible_menu = 1;
29731            clearTimeout(timer_menu);
29732
29733          }, function () {
29734
29735            // var $this = $(this);
29736            clearTimeout(timer_menu);
29737
29738            if (visible_menu === 1) {
29739              // $this.stop(true).delay(speed_menu).slideUp(speed_menu);
29740              $('.header__menu').find('.active').removeClass('active');
29741              $('.megamenu').removeClass('megamenu--active');
29742              $('.megamenu__item').removeClass('megamenu__item--active');
29743              visible_menu = 0;
29744            }
29745
29746          });
29747
29748        }
29749      }
29750
29751      /**
29752       * @return
29753       */
29754      return {
29755        init: function () {
29756          Install();
29757          Megamenu();
29758        },
29759      };
29760    }();
29761
29762    /**
29763     * Init Header
29764     */
29765    Header.init();
29766
29767    /**
29768     * TourHeader
29769     * @type {{init: init}}
29770     */
29771    var TourPage = function () {
29772
29773      /**
29774       * Header
29775       * @param data
29776       * @constructor
29777       */
29778      var Header = function () {
29779
29780        /**
29781         * Scroll Page
29782         * @scroll
29783         */
29784        $(window).on('scroll', function () {
29785
29786          var windowPosition = $(window).scrollTop();
29787
29788          if( windowPosition > 0 ) {
29789            $('.header_tour').addClass('scroll')
29790          }else{
29791            $('.header_tour').removeClass('scroll')
29792          }
29793
29794
29795        }).scroll();
29796
29797      }
29798
29799      /**
29800       * Show Wrapper
29801       * @constructor
29802       */
29803      var ShowWrapper = function () {
29804
29805        $('.tour').css('opacity', 1);
29806
29807        setTimeout(function () {
29808
29809          $('.tour__preloader').stop().animate({
29810            opacity: 0,
29811          }, 400, function () {
29812
29813            $('.tour__preloader').remove();
29814            $('body').addClass('isLoaded');
29815
29816          });
29817
29818        }, 100);
29819
29820      }
29821
29822      /**
29823       * Install
29824       * @param data
29825       * @constructor
29826       */
29827      var Install = function () {
29828
29829        $('.tour').imagesLoaded()
29830          // eslint-disable-next-line no-unused-vars
29831          .always( function( instance ) {
29832            console.log('all images loaded');
29833          })
29834          // eslint-disable-next-line no-unused-vars
29835          .done( function( instance ) {
29836
29837            ShowWrapper();
29838
29839          })
29840          .fail( function() {
29841            console.log('all images loaded, at least one is broken');
29842
29843            ShowWrapper();
29844
29845          })
29846          // eslint-disable-next-line no-unused-vars
29847          .progress( function( instance, image ) {
29848            //var result = image.isLoaded ? 'loaded' : 'broken';
29849          });
29850
29851      }
29852
29853      /**
29854       * Megamenu
29855       * @constructor
29856       */
29857      var Megamenu = function () {
29858
29859        /**
29860         * Swiper Megamenu
29861         */
29862        if ( $('.header_tour__megamenu__slider').length > 0 ) {
29863
29864          var swiperMegamenu = {};
29865          $('.header_tour__megamenu__slider').each(function (index) {
29866            var $this = $(this);
29867            $this.addClass('swiperMegamenu-' + index);
29868
29869            swiperMegamenu[index] =  new __WEBPACK_IMPORTED_MODULE_5_swiper_bundle__["a" /* default */]('.swiperMegamenu-' + index + ' .swiper-container', {
29870              slidesPerView         : 'auto',
29871              spaceBetween          : 8,
29872              loop                  : false,
29873              speed                 : 500,
29874              observer              : true,
29875              observeParents        : true,
29876              observeSlideChildren  : true,
29877              slidesOffsetBefore    : 44,
29878              pagination: {
29879                el          : '.swiperMegamenu-' + index + ' .swiper-pagination',
29880                clickable   : true,
29881                type        : 'bullets',
29882              },
29883              navigation: {
29884                nextEl      : '.swiperMegamenu-' + index + ' .swiper-button-next',
29885                prevEl      : '.swiperMegamenu-' + index + ' .swiper-button-prev',
29886              },
29887              breakpoints: {
29888                1023: {
29889                  spaceBetween          : 12,
29890                  slidesOffsetBefore    : 0,
29891                },
29892              },
29893            });
29894
29895          });
29896
29897
29898
29899
29900
29901        }
29902      }
29903
29904      /**
29905       * Cards
29906       * @constructor
29907       */
29908      var Cards = function () {
29909
29910
29911      }
29912
29913
29914      /**
29915       * @return
29916       */
29917      return {
29918        init: function () {
29919          Install();
29920          Header();
29921          Megamenu();
29922          Cards();
29923        },
29924      };
29925    }();
29926
29927    /**
29928     * Init Tour Page
29929     */
29930    if( $('.tour').length ) {
29931      TourPage.init();
29932    }
29933
29934    /**
29935     * breadcrumbs
29936     * @length
29937     * @each
29938     */
29939    if ($('.breadcrumbs').length) {
29940
29941      $('.breadcrumbs li').each(function () {
29942
29943        if ($(this).find('ul').length) {
29944
29945          $(this).addClass('breadcrumbs__dropdown');
29946
29947        }
29948
29949      });
29950
29951      /**
29952       * Hide Breadcrumbs DropDown
29953       * @mouseup
29954       */
29955      $(document).mouseup(function (e) {
29956
29957        var container = $('.breadcrumbs__dropdown');
29958
29959        if (container.has(e.target).length === 0) {
29960
29961          container.removeClass('active');
29962
29963        }
29964
29965      });
29966
29967    }
29968
29969    /**
29970     * Breadcrumbs
29971     * @click
29972     */
29973    $(document).on('click', '.breadcrumbs__dropdown > a', function (e) {
29974
29975      $(this).parent().toggleClass('active');
29976
29977      e.preventDefault();
29978
29979    });
29980
29981    /**
29982     * News & Events
29983     * @Masonry
29984     */
29985    if ($('.newseventsMasonry').length) {
29986
29987      $('.newseventsMasonry').each(function (index) {
29988
29989        var $elem = 'masonry-newsevents-' + index;
29990
29991        $(this).addClass($elem);
29992
29993        var $masonry = '.' + $elem;
29994
29995        var $grid = {};
29996
29997        $grid[index] = new __WEBPACK_IMPORTED_MODULE_0_masonry_layout___default.a($masonry, {
29998          percentPosition: true,
29999          itemSelector: '.newseventsMasonry-item',
30000          gutter: 0,
30001          transitionDuration: 0,
30002          columnWidth: '.grid-sizer',
30003        });
30004
30005        $(window).on('load resize', function () {
30006          $grid[index].reloadItems();
30007          $grid[index].layout();
30008        });
30009
30010      });
30011
30012    }
30013
30014    /**
30015     * Open Nav Mobile Left Sidebar
30016     */
30017    $(document).on('click', '.openNavSection', function (e) {
30018
30019      $(this).toggleClass('active');
30020      $(this).parent().find('ul').toggleClass('open');
30021      e.preventDefault();
30022
30023    });
30024
30025    /**
30026     * header Search
30027     */
30028    $('.top-header__search').on('click', function (e) {
30029      e.preventDefault();
30030      $(this).addClass('top-header__search--active');
30031    });
30032
30033    /**
30034     * header Search
30035     */
30036    $(document).on('click', '.top-header__search__icon', function (e) {
30037
30038      $(this).closest('form').trigger('submit');
30039      e.preventDefault();
30040
30041    });
30042
30043    /**
30044     * page Search
30045     */
30046    $(document).on('click', '.dropSearchOrder', function (e) {
30047
30048      $('.dropSearchDropdown').toggleClass('active');
30049      e.preventDefault();
30050
30051    });
30052
30053    $(document).mouseup(function (e) {
30054      var div = $('.dropSearchDropdown');
30055      if (!div.is(e.target)
30056        && div.has(e.target).length === 0) {
30057        div.removeClass('active');
30058      }
30059    });
30060
30061    /**
30062     * Replace all SVG images with inline SVG
30063     */
30064    jQuery('img.svg').each(function () {
30065      var $img = jQuery(this);
30066      var imgID = $img.attr('id');
30067      var imgClass = $img.attr('class');
30068      var imgURL = $img.attr('src');
30069
30070      jQuery.get(imgURL, function (data) {
30071        // Get the SVG tag, ignore the rest
30072        var $svg = jQuery(data).find('svg');
30073
30074        // Add replaced image ID to the new SVG
30075        if (typeof imgID !== 'undefined') {
30076          $svg = $svg.attr('id', imgID);
30077        }
30078        // Add replaced image classes to the new SVG
30079        if (typeof imgClass !== 'undefined') {
30080          $svg = $svg.attr('class', imgClass + ' replaced-svg');
30081        }
30082
30083        // Remove any invalid XML tags as per http://validator.w3.org
30084        $svg = $svg.removeAttr('xmlns:a');
30085
30086        // Check if the viewport is set, if the viewport is not set the SVG wont't scale.
30087        if (!$svg.attr('viewBox') && $svg.attr('height') && $svg.attr('width')) {
30088          $svg.attr('viewBox', '0 0 ' + $svg.attr('height') + ' ' + $svg.attr('width'))
30089        }
30090
30091        // Replace image with new SVG
30092        $img.replaceWith($svg);
30093
30094      }, 'xml');
30095
30096    });
30097
30098
30099    $(document).on('click', '.closeFloatingSection', function () {
30100      $('.floating_section').remove();
30101    });
30102
30103    var userScrolled = false;
30104    var refreshspeed = 1000 / 10;
30105
30106    $(window).on('scroll', function () {
30107
30108      var windowPosition = $(window).scrollTop(),
30109        topPanel = $('.top-header__inner').outerHeight();
30110
30111      if (windowPosition > topPanel) {
30112        $('header.header').addClass('stiky');
30113        $('.main').addClass('active');
30114      } else {
30115        $('header.header').removeClass('stiky');
30116        $('.main').removeClass('active');
30117      }
30118
30119      userScrolled = true;
30120
30121    }).scroll();
30122
30123    function isOnScreen(x) {
30124      if (x.length) {
30125        var top_of_element = x.offset().top;
30126        var bottom_of_screen = $(window).scrollTop() + window.innerHeight - 300;
30127        return bottom_of_screen > top_of_element;
30128      }
30129    }
30130
30131    executeOnScroll();
30132
30133    function executeOnScroll() {
30134      $('.fadein, .animated').each(function () {
30135        if (isOnScreen($(this))) {
30136          $(this).addClass('onscreen');
30137        }
30138      });
30139    }
30140
30141    function checkIfScrolled() {
30142      if (userScrolled) {
30143        window.requestAnimationFrame(executeOnScroll);
30144        userScrolled = false;
30145      }
30146    }
30147
30148    setInterval(checkIfScrolled, refreshspeed);
30149
30150    $(document).on('click', '.to_top__link', function (e) {
30151      e.preventDefault();
30152      $('html, body').animate({scrollTop: 0}, 1000);
30153    });
30154
30155    if(window.location.hash) {
30156      //Url from a different page:
30157      var hashID = window.location.hash.replace('#', '');
30158
30159      console.log(hashID);
30160
30161      $('#' + (hashID)).addClass('active');
30162    }
30163
30164    $('.dynamic__navsections-list a[href^="#"]').on('click', function(){
30165      var anchor = $(this).attr('href').replace('#', '');
30166
30167      console.log(anchor);
30168
30169      $('.dynamic__accordion-list').find('#' + anchor).addClass('active');
30170    });
30171
30172    /**
30173     * ArchivePost
30174     * @type {{init: init}}
30175     */
30176    var ArchivePost = function () {
30177
30178      var loader = {message: '', overlayCSS: {background: '#fff', opacity: 0.6}};
30179
30180      /**
30181       * Install
30182       * @param data
30183       * @constructor
30184       */
30185      var Install = function () {
30186
30187        /**
30188         *
30189         * @type {*|string}
30190         */
30191        var url_string = window.location.href,
30192          url = new URL(url_string),
30193          category = url.searchParams.get('category');
30194
30195        if (category > 0) {
30196
30197          $('.ArchivePostCatLinkAll').prop('checked', false);
30198          $('[name="program[' + category + ']"]').prop('checked', true);
30199          $('.ArchivePostCat').val(category + ',');
30200          Ajax();
30201
30202        }
30203
30204        /**
30205         * Datepicker
30206         */
30207
30208        var $datepicker = $('.archive_section .date_picker_value'),
30209          $button = $('.archive_section .date_picker_button'),
30210          $paged = $('.ArchivePostForm [name="paged"]');
30211
30212        $datepicker.datepicker({
30213          dateFormat: 'dd M yy',
30214          beforeShow: function () {
30215
30216            $('.date_picker').append($('#ui-datepicker-div')).ready(function () {
30217                $('#ui-datepicker-div').prepend(
30218                  $('<input type="text" value="" placeholder="mm/dd/yyyy" class="ui-input">')
30219                    .mask(
30220                      '99/99/9999',
30221                      {
30222                        completed: function () {
30223
30224                          $datepicker.datepicker('hide');
30225
30226                          var theDate = new Date(this.val()),
30227                            dateFormatted = $.datepicker.formatDate('yy-mm-dd', theDate);
30228
30229                          $datepicker.val(dateFormatted);
30230                          $button.text(Object(__WEBPACK_IMPORTED_MODULE_1_moment_dist_moment__["a" /* default */])(dateFormatted).format('MMM YYYY'));
30231
30232                          $datepicker.datepicker('setDate', new Date(dateFormatted));
30233
30234                          $('[name="type_date"]').val('date');
30235                          $('[name="date"]').val(dateFormatted);
30236
30237                          $paged.val(1);
30238
30239                          Ajax();
30240                        },
30241                      }
30242                    )
30243                );
30244              }
30245            );
30246
30247          },
30248          onSelect: function (date) {
30249            $button.text(date);
30250
30251            console.log('--7')
30252            var theDate = new Date(Date.parse($(this).datepicker('getDate'))),
30253              dateFormatted = $.datepicker.formatDate('yy-mm-dd', theDate);
30254
30255            $datepicker.val(dateFormatted);
30256
30257            $datepicker.datepicker('setDate', new Date(dateFormatted));
30258
30259            $('[name="type_date"]').val('date');
30260            $('[name="date"]').val(dateFormatted);
30261
30262            Ajax();
30263
30264          },
30265          onChangeMonthYear: function () {
30266            $('.date_picker').append($('#ui-datepicker-div')).ready(function () {
30267              $('#ui-datepicker-div').prepend($('<input type="text" value="" placeholder="mm/dd/yyyy" class="ui-input">').mask('99/99/9999'));
30268            });
30269          },
30270        });
30271
30272        /**
30273         * Open Datepicker
30274         */
30275        $(document).on('click', '.archive_section .date_picker_button', function () {
30276          $datepicker.show().focus().hide();
30277        });
30278
30279        /**
30280         * Next and Prev Month
30281         * @click
30282         */
30283        $(document).on('click', '.archive_section .filterNewsEventMonth', function () {
30284          console.log('--6')
30285
30286          var $this = $(this),
30287            $inp = $datepicker,
30288            //data = $inp.val(),
30289            data = $inp.datepicker( 'getDate' ),
30290            now = new Date(data),
30291            future = null;
30292
30293          if ($this.hasClass('filterNewsEventMonthNext')) {
30294            future = now.setMonth(new Date(now.getTime() + 36000 * 600).getMonth() + 1, 1);
30295          }
30296
30297          if ($this.hasClass('filterNewsEventMonthPrev')) {
30298            future = now.setMonth(new Date(now.getTime() + 36000 * 600).getMonth() - 1, 1);
30299          }
30300
30301
30302
30303          $button.text(Object(__WEBPACK_IMPORTED_MODULE_1_moment_dist_moment__["a" /* default */])(future).format('MMM YYYY'));
30304          //$inp.val(moment(future).format('YYYY-MM-DD'));
30305          $inp.datepicker('setDate', new Date(future) );
30306
30307          $('[name="type_date"]').val('month');
30308          $('[name="date"]').val(Object(__WEBPACK_IMPORTED_MODULE_1_moment_dist_moment__["a" /* default */])(future).format('YYYY-MM-DD'));
30309
30310          $(this).block(loader);
30311
30312          $paged.val(1);
30313
30314          Ajax();
30315
30316        });
30317
30318        /**
30319         * ArchivePostCatLink
30320         * @change
30321         *
30322         */
30323        $(document).on('change', '.ArchivePostCatLinkItem', function () {
30324          console.log('--5')
30325
30326          var $inp = $('.ArchivePostCat'),
30327            def_value = $inp.val(),
30328            $this = $(this);
30329
30330          if ($this.is(':checked')) {
30331
30332            $inp.val(def_value + $this.val() + ',');
30333
30334          } else {
30335
30336            $inp.val(function (index, value) {
30337              return value.replace($this.val() + ',', '');
30338            });
30339
30340          }
30341
30342          //$('[name="type_date"]').val('');
30343
30344          if ($inp.val().length == 0) {
30345            $('.ArchivePostCatLinkAll').prop('checked', true);
30346          } else {
30347            $('.ArchivePostCatLinkAll').prop('checked', false);
30348          }
30349
30350          $paged.val(1);
30351          Ajax();
30352
30353        });
30354
30355        /**
30356         * All Category
30357         */
30358        $(document).on('change', '.ArchivePostCatLinkAll', function () {
30359          console.log('--4')
30360          $(this).prop('checked', true);
30361          $('.ArchivePostCat').val('');
30362          $('.ArchivePostCatLinkItem').prop('checked', false);
30363
30364          $paged.val(1);
30365          Ajax();
30366        });
30367
30368        /**
30369         * Pagination
30370         */
30371        $(document).on('click', '.ArchivePostPagination a', function (e) {
30372          console.log('--3')
30373
30374          var arr = $(this).attr('href').split('/');
30375
30376          arr = arr.filter(function (e) {
30377            return e
30378          });
30379
30380          var number = arr.pop();
30381
30382          $paged.val(number);
30383
30384          Ajax();
30385
30386          e.preventDefault()
30387        });
30388
30389      }
30390
30391      /**
30392       * Ajax
30393       * @param data
30394       * @constructor
30395       */
30396      var Ajax = function (data) {
30397        if ( data === void 0 ) data = '';
30398
30399
30400        /**
30401         *
30402         * @type {jQuery|HTMLElement}
30403         */
30404        var $form = $('.ArchivePostForm'),
30405          $container_result = $('.resultAjax');
30406        /**
30407         * Data
30408         * @type {string}
30409         */
30410        data += $form.serialize() + '&month=';
30411
30412        $.ajax({
30413          beforeSend: function () {
30414            $container_result.block(loader);
30415          },
30416          data: data,
30417          dataType: 'json',
30418          method: 'POST',
30419          complete: function () {
30420            $container_result.unblock();
30421            $('.filterNewsEventMonthPrev').unblock();
30422            $('.filterNewsEventMonthNext').unblock();
30423          },
30424          success: function (response) {
30425
30426
30427            /**
30428             * Html
30429             */
30430            $container_result.html(response.data.html).ready(function () {
30431
30432              if( $('.newseventsMasonry').length ) {
30433
30434                var grid = new __WEBPACK_IMPORTED_MODULE_0_masonry_layout___default.a('.newseventsMasonry');
30435                grid.reloadItems();
30436                setTimeout(function () {
30437                  grid = new __WEBPACK_IMPORTED_MODULE_0_masonry_layout___default.a('.newseventsMasonry', {
30438                    percentPosition: true,
30439                    itemSelector: '.newseventsMasonry-item',
30440                    isInitLayout: true,
30441                    gutter: 0,
30442                    transitionDuration: 0,
30443                    columnWidth: '.grid-sizer',
30444                  });
30445                }, 200)
30446
30447              }
30448            });
30449
30450            /**
30451             * Masonry
30452             */
30453            $(window).trigger('resize');
30454
30455            /**
30456             * Month Panel
30457             */
30458            // $month_panel.html(response.data.month);
30459
30460          },
30461          url: window.nec.ajax_url,
30462        });
30463
30464      }
30465
30466      /**
30467       * @return
30468       */
30469      return {
30470        init: function () {
30471          Install();
30472
30473        },
30474      };
30475    }();
30476
30477    /**
30478     * Init Header
30479     */
30480    ArchivePost.init();
30481  },
30482});
30483
30484/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(2), __webpack_require__(2)))
30485
30486/***/ }),
30487/* 156 */
30488/***/ (function(module, exports, __webpack_require__) {
30489
30490var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
30491 * Outlayer v2.1.1
30492 * the brains and guts of a layout library
30493 * MIT license
30494 */
30495
30496( function( window, factory ) {
30497  'use strict';
30498  // universal module definition
30499  /* jshint strict: false */ /* globals define, module, require */
30500  if ( true ) {
30501    // AMD - RequireJS
30502    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
30503        __webpack_require__(8),
30504        __webpack_require__(9),
30505        __webpack_require__(157),
30506        __webpack_require__(159)
30507      ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( EvEmitter, getSize, utils, Item ) {
30508        return factory( window, EvEmitter, getSize, utils, Item);
30509      }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
30510				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)
vendor: 21,459 bytes, lines 30510-31428
30510);
30511  } else if ( typeof module == 'object' && module.exports ) {
30512    // CommonJS - Browserify, Webpack
30513    module.exports = factory(
30514      window,
30515      require('ev-emitter'),
30516      require('get-size'),
30517      require('fizzy-ui-utils'),
30518      require('./item')
30519    );
30520  } else {
30521    // browser global
30522    window.Outlayer = factory(
30523      window,
30524      window.EvEmitter,
30525      window.getSize,
30526      window.fizzyUIUtils,
30527      window.Outlayer.Item
30528    );
30529  }
30530
30531}( window, function factory( window, EvEmitter, getSize, utils, Item ) {
30532'use strict';
30533
30534// ----- vars ----- //
30535
30536var console = window.console;
30537var jQuery = window.jQuery;
30538var noop = function() {};
30539
30540// -------------------------- Outlayer -------------------------- //
30541
30542// globally unique identifiers
30543var GUID = 0;
30544// internal store of all Outlayer intances
30545var instances = {};
30546
30547
30548/**
30549 * @param {Element, String} element
30550 * @param {Object} options
30551 * @constructor
30552 */
30553function Outlayer( element, options ) {
30554  var queryElement = utils.getQueryElement( element );
30555  if ( !queryElement ) {
30556    if ( console ) {
30557      console.error( 'Bad element for ' + this.constructor.namespace +
30558        ': ' + ( queryElement || element ) );
30559    }
30560    return;
30561  }
30562  this.element = queryElement;
30563  // add jQuery
30564  if ( jQuery ) {
30565    this.$element = jQuery( this.element );
30566  }
30567
30568  // options
30569  this.options = utils.extend( {}, this.constructor.defaults );
30570  this.option( options );
30571
30572  // add id for Outlayer.getFromElement
30573  var id = ++GUID;
30574  this.element.outlayerGUID = id; // expando
30575  instances[ id ] = this; // associate via id
30576
30577  // kick it off
30578  this._create();
30579
30580  var isInitLayout = this._getOption('initLayout');
30581  if ( isInitLayout ) {
30582    this.layout();
30583  }
30584}
30585
30586// settings are for internal use only
30587Outlayer.namespace = 'outlayer';
30588Outlayer.Item = Item;
30589
30590// default options
30591Outlayer.defaults = {
30592  containerStyle: {
30593    position: 'relative'
30594  },
30595  initLayout: true,
30596  originLeft: true,
30597  originTop: true,
30598  resize: true,
30599  resizeContainer: true,
30600  // item options
30601  transitionDuration: '0.4s',
30602  hiddenStyle: {
30603    opacity: 0,
30604    transform: 'scale(0.001)'
30605  },
30606  visibleStyle: {
30607    opacity: 1,
30608    transform: 'scale(1)'
30609  }
30610};
30611
30612var proto = Outlayer.prototype;
30613// inherit EvEmitter
30614utils.extend( proto, EvEmitter.prototype );
30615
30616/**
30617 * set options
30618 * @param {Object} opts
30619 */
30620proto.option = function( opts ) {
30621  utils.extend( this.options, opts );
30622};
30623
30624/**
30625 * get backwards compatible option value, check old name
30626 */
30627proto._getOption = function( option ) {
30628  var oldOption = this.constructor.compatOptions[ option ];
30629  return oldOption && this.options[ oldOption ] !== undefined ?
30630    this.options[ oldOption ] : this.options[ option ];
30631};
30632
30633Outlayer.compatOptions = {
30634  // currentName: oldName
30635  initLayout: 'isInitLayout',
30636  horizontal: 'isHorizontal',
30637  layoutInstant: 'isLayoutInstant',
30638  originLeft: 'isOriginLeft',
30639  originTop: 'isOriginTop',
30640  resize: 'isResizeBound',
30641  resizeContainer: 'isResizingContainer'
30642};
30643
30644proto._create = function() {
30645  // get items from children
30646  this.reloadItems();
30647  // elements that affect layout, but are not laid out
30648  this.stamps = [];
30649  this.stamp( this.options.stamp );
30650  // set container style
30651  utils.extend( this.element.style, this.options.containerStyle );
30652
30653  // bind resize method
30654  var canBindResize = this._getOption('resize');
30655  if ( canBindResize ) {
30656    this.bindResize();
30657  }
30658};
30659
30660// goes through all children again and gets bricks in proper order
30661proto.reloadItems = function() {
30662  // collection of item elements
30663  this.items = this._itemize( this.element.children );
30664};
30665
30666
30667/**
30668 * turn elements into Outlayer.Items to be used in layout
30669 * @param {Array or NodeList or HTMLElement} elems
30670 * @returns {Array} items - collection of new Outlayer Items
30671 */
30672proto._itemize = function( elems ) {
30673
30674  var itemElems = this._filterFindItemElements( elems );
30675  var Item = this.constructor.Item;
30676
30677  // create new Outlayer Items for collection
30678  var items = [];
30679  for ( var i=0; i < itemElems.length; i++ ) {
30680    var elem = itemElems[i];
30681    var item = new Item( elem, this );
30682    items.push( item );
30683  }
30684
30685  return items;
30686};
30687
30688/**
30689 * get item elements to be used in layout
30690 * @param {Array or NodeList or HTMLElement} elems
30691 * @returns {Array} items - item elements
30692 */
30693proto._filterFindItemElements = function( elems ) {
30694  return utils.filterFindElements( elems, this.options.itemSelector );
30695};
30696
30697/**
30698 * getter method for getting item elements
30699 * @returns {Array} elems - collection of item elements
30700 */
30701proto.getItemElements = function() {
30702  return this.items.map( function( item ) {
30703    return item.element;
30704  });
30705};
30706
30707// ----- init & layout ----- //
30708
30709/**
30710 * lays out all items
30711 */
30712proto.layout = function() {
30713  this._resetLayout();
30714  this._manageStamps();
30715
30716  // don't animate first layout
30717  var layoutInstant = this._getOption('layoutInstant');
30718  var isInstant = layoutInstant !== undefined ?
30719    layoutInstant : !this._isLayoutInited;
30720  this.layoutItems( this.items, isInstant );
30721
30722  // flag for initalized
30723  this._isLayoutInited = true;
30724};
30725
30726// _init is alias for layout
30727proto._init = proto.layout;
30728
30729/**
30730 * logic before any new layout
30731 */
30732proto._resetLayout = function() {
30733  this.getSize();
30734};
30735
30736
30737proto.getSize = function() {
30738  this.size = getSize( this.element );
30739};
30740
30741/**
30742 * get measurement from option, for columnWidth, rowHeight, gutter
30743 * if option is String -> get element from selector string, & get size of element
30744 * if option is Element -> get size of element
30745 * else use option as a number
30746 *
30747 * @param {String} measurement
30748 * @param {String} size - width or height
30749 * @private
30750 */
30751proto._getMeasurement = function( measurement, size ) {
30752  var option = this.options[ measurement ];
30753  var elem;
30754  if ( !option ) {
30755    // default to 0
30756    this[ measurement ] = 0;
30757  } else {
30758    // use option as an element
30759    if ( typeof option == 'string' ) {
30760      elem = this.element.querySelector( option );
30761    } else if ( option instanceof HTMLElement ) {
30762      elem = option;
30763    }
30764    // use size of element, if element
30765    this[ measurement ] = elem ? getSize( elem )[ size ] : option;
30766  }
30767};
30768
30769/**
30770 * layout a collection of item elements
30771 * @api public
30772 */
30773proto.layoutItems = function( items, isInstant ) {
30774  items = this._getItemsForLayout( items );
30775
30776  this._layoutItems( items, isInstant );
30777
30778  this._postLayout();
30779};
30780
30781/**
30782 * get the items to be laid out
30783 * you may want to skip over some items
30784 * @param {Array} items
30785 * @returns {Array} items
30786 */
30787proto._getItemsForLayout = function( items ) {
30788  return items.filter( function( item ) {
30789    return !item.isIgnored;
30790  });
30791};
30792
30793/**
30794 * layout items
30795 * @param {Array} items
30796 * @param {Boolean} isInstant
30797 */
30798proto._layoutItems = function( items, isInstant ) {
30799  this._emitCompleteOnItems( 'layout', items );
30800
30801  if ( !items || !items.length ) {
30802    // no items, emit event with empty array
30803    return;
30804  }
30805
30806  var queue = [];
30807
30808  items.forEach( function( item ) {
30809    // get x/y object from method
30810    var position = this._getItemLayoutPosition( item );
30811    // enqueue
30812    position.item = item;
30813    position.isInstant = isInstant || item.isLayoutInstant;
30814    queue.push( position );
30815  }, this );
30816
30817  this._processLayoutQueue( queue );
30818};
30819
30820/**
30821 * get item layout position
30822 * @param {Outlayer.Item} item
30823 * @returns {Object} x and y position
30824 */
30825proto._getItemLayoutPosition = function( /* item */ ) {
30826  return {
30827    x: 0,
30828    y: 0
30829  };
30830};
30831
30832/**
30833 * iterate over array and position each item
30834 * Reason being - separating this logic prevents 'layout invalidation'
30835 * thx @paul_irish
30836 * @param {Array} queue
30837 */
30838proto._processLayoutQueue = function( queue ) {
30839  this.updateStagger();
30840  queue.forEach( function( obj, i ) {
30841    this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );
30842  }, this );
30843};
30844
30845// set stagger from option in milliseconds number
30846proto.updateStagger = function() {
30847  var stagger = this.options.stagger;
30848  if ( stagger === null || stagger === undefined ) {
30849    this.stagger = 0;
30850    return;
30851  }
30852  this.stagger = getMilliseconds( stagger );
30853  return this.stagger;
30854};
30855
30856/**
30857 * Sets position of item in DOM
30858 * @param {Outlayer.Item} item
30859 * @param {Number} x - horizontal position
30860 * @param {Number} y - vertical position
30861 * @param {Boolean} isInstant - disables transitions
30862 */
30863proto._positionItem = function( item, x, y, isInstant, i ) {
30864  if ( isInstant ) {
30865    // if not transition, just set CSS
30866    item.goTo( x, y );
30867  } else {
30868    item.stagger( i * this.stagger );
30869    item.moveTo( x, y );
30870  }
30871};
30872
30873/**
30874 * Any logic you want to do after each layout,
30875 * i.e. size the container
30876 */
30877proto._postLayout = function() {
30878  this.resizeContainer();
30879};
30880
30881proto.resizeContainer = function() {
30882  var isResizingContainer = this._getOption('resizeContainer');
30883  if ( !isResizingContainer ) {
30884    return;
30885  }
30886  var size = this._getContainerSize();
30887  if ( size ) {
30888    this._setContainerMeasure( size.width, true );
30889    this._setContainerMeasure( size.height, false );
30890  }
30891};
30892
30893/**
30894 * Sets width or height of container if returned
30895 * @returns {Object} size
30896 *   @param {Number} width
30897 *   @param {Number} height
30898 */
30899proto._getContainerSize = noop;
30900
30901/**
30902 * @param {Number} measure - size of width or height
30903 * @param {Boolean} isWidth
30904 */
30905proto._setContainerMeasure = function( measure, isWidth ) {
30906  if ( measure === undefined ) {
30907    return;
30908  }
30909
30910  var elemSize = this.size;
30911  // add padding and border width if border box
30912  if ( elemSize.isBorderBox ) {
30913    measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
30914      elemSize.borderLeftWidth + elemSize.borderRightWidth :
30915      elemSize.paddingBottom + elemSize.paddingTop +
30916      elemSize.borderTopWidth + elemSize.borderBottomWidth;
30917  }
30918
30919  measure = Math.max( measure, 0 );
30920  this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
30921};
30922
30923/**
30924 * emit eventComplete on a collection of items events
30925 * @param {String} eventName
30926 * @param {Array} items - Outlayer.Items
30927 */
30928proto._emitCompleteOnItems = function( eventName, items ) {
30929  var _this = this;
30930  function onComplete() {
30931    _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
30932  }
30933
30934  var count = items.length;
30935  if ( !items || !count ) {
30936    onComplete();
30937    return;
30938  }
30939
30940  var doneCount = 0;
30941  function tick() {
30942    doneCount++;
30943    if ( doneCount == count ) {
30944      onComplete();
30945    }
30946  }
30947
30948  // bind callback
30949  items.forEach( function( item ) {
30950    item.once( eventName, tick );
30951  });
30952};
30953
30954/**
30955 * emits events via EvEmitter and jQuery events
30956 * @param {String} type - name of event
30957 * @param {Event} event - original event
30958 * @param {Array} args - extra arguments
30959 */
30960proto.dispatchEvent = function( type, event, args ) {
30961  // add original event to arguments
30962  var emitArgs = event ? [ event ].concat( args ) : args;
30963  this.emitEvent( type, emitArgs );
30964
30965  if ( jQuery ) {
30966    // set this.$element
30967    this.$element = this.$element || jQuery( this.element );
30968    if ( event ) {
30969      // create jQuery event
30970      var $event = jQuery.Event( event );
30971      $event.type = type;
30972      this.$element.trigger( $event, args );
30973    } else {
30974      // just trigger with type if no event available
30975      this.$element.trigger( type, args );
30976    }
30977  }
30978};
30979
30980// -------------------------- ignore & stamps -------------------------- //
30981
30982
30983/**
30984 * keep item in collection, but do not lay it out
30985 * ignored items do not get skipped in layout
30986 * @param {Element} elem
30987 */
30988proto.ignore = function( elem ) {
30989  var item = this.getItem( elem );
30990  if ( item ) {
30991    item.isIgnored = true;
30992  }
30993};
30994
30995/**
30996 * return item to layout collection
30997 * @param {Element} elem
30998 */
30999proto.unignore = function( elem ) {
31000  var item = this.getItem( elem );
31001  if ( item ) {
31002    delete item.isIgnored;
31003  }
31004};
31005
31006/**
31007 * adds elements to stamps
31008 * @param {NodeList, Array, Element, or String} elems
31009 */
31010proto.stamp = function( elems ) {
31011  elems = this._find( elems );
31012  if ( !elems ) {
31013    return;
31014  }
31015
31016  this.stamps = this.stamps.concat( elems );
31017  // ignore
31018  elems.forEach( this.ignore, this );
31019};
31020
31021/**
31022 * removes elements to stamps
31023 * @param {NodeList, Array, or Element} elems
31024 */
31025proto.unstamp = function( elems ) {
31026  elems = this._find( elems );
31027  if ( !elems ){
31028    return;
31029  }
31030
31031  elems.forEach( function( elem ) {
31032    // filter out removed stamp elements
31033    utils.removeFrom( this.stamps, elem );
31034    this.unignore( elem );
31035  }, this );
31036};
31037
31038/**
31039 * finds child elements
31040 * @param {NodeList, Array, Element, or String} elems
31041 * @returns {Array} elems
31042 */
31043proto._find = function( elems ) {
31044  if ( !elems ) {
31045    return;
31046  }
31047  // if string, use argument as selector string
31048  if ( typeof elems == 'string' ) {
31049    elems = this.element.querySelectorAll( elems );
31050  }
31051  elems = utils.makeArray( elems );
31052  return elems;
31053};
31054
31055proto._manageStamps = function() {
31056  if ( !this.stamps || !this.stamps.length ) {
31057    return;
31058  }
31059
31060  this._getBoundingRect();
31061
31062  this.stamps.forEach( this._manageStamp, this );
31063};
31064
31065// update boundingLeft / Top
31066proto._getBoundingRect = function() {
31067  // get bounding rect for container element
31068  var boundingRect = this.element.getBoundingClientRect();
31069  var size = this.size;
31070  this._boundingRect = {
31071    left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
31072    top: boundingRect.top + size.paddingTop + size.borderTopWidth,
31073    right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
31074    bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
31075  };
31076};
31077
31078/**
31079 * @param {Element} stamp
31080**/
31081proto._manageStamp = noop;
31082
31083/**
31084 * get x/y position of element relative to container element
31085 * @param {Element} elem
31086 * @returns {Object} offset - has left, top, right, bottom
31087 */
31088proto._getElementOffset = function( elem ) {
31089  var boundingRect = elem.getBoundingClientRect();
31090  var thisRect = this._boundingRect;
31091  var size = getSize( elem );
31092  var offset = {
31093    left: boundingRect.left - thisRect.left - size.marginLeft,
31094    top: boundingRect.top - thisRect.top - size.marginTop,
31095    right: thisRect.right - boundingRect.right - size.marginRight,
31096    bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
31097  };
31098  return offset;
31099};
31100
31101// -------------------------- resize -------------------------- //
31102
31103// enable event handlers for listeners
31104// i.e. resize -> onresize
31105proto.handleEvent = utils.handleEvent;
31106
31107/**
31108 * Bind layout to window resizing
31109 */
31110proto.bindResize = function() {
31111  window.addEventListener( 'resize', this );
31112  this.isResizeBound = true;
31113};
31114
31115/**
31116 * Unbind layout to window resizing
31117 */
31118proto.unbindResize = function() {
31119  window.removeEventListener( 'resize', this );
31120  this.isResizeBound = false;
31121};
31122
31123proto.onresize = function() {
31124  this.resize();
31125};
31126
31127utils.debounceMethod( Outlayer, 'onresize', 100 );
31128
31129proto.resize = function() {
31130  // don't trigger if size did not change
31131  // or if resize was unbound. See #9
31132  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
31133    return;
31134  }
31135
31136  this.layout();
31137};
31138
31139/**
31140 * check if layout is needed post layout
31141 * @returns Boolean
31142 */
31143proto.needsResizeLayout = function() {
31144  var size = getSize( this.element );
31145  // check that this.size and size are there
31146  // IE8 triggers resize on body size change, so they might not be
31147  var hasSizes = this.size && size;
31148  return hasSizes && size.innerWidth !== this.size.innerWidth;
31149};
31150
31151// -------------------------- methods -------------------------- //
31152
31153/**
31154 * add items to Outlayer instance
31155 * @param {Array or NodeList or Element} elems
31156 * @returns {Array} items - Outlayer.Items
31157**/
31158proto.addItems = function( elems ) {
31159  var items = this._itemize( elems );
31160  // add items to collection
31161  if ( items.length ) {
31162    this.items = this.items.concat( items );
31163  }
31164  return items;
31165};
31166
31167/**
31168 * Layout newly-appended item elements
31169 * @param {Array or NodeList or Element} elems
31170 */
31171proto.appended = function( elems ) {
31172  var items = this.addItems( elems );
31173  if ( !items.length ) {
31174    return;
31175  }
31176  // layout and reveal just the new items
31177  this.layoutItems( items, true );
31178  this.reveal( items );
31179};
31180
31181/**
31182 * Layout prepended elements
31183 * @param {Array or NodeList or Element} elems
31184 */
31185proto.prepended = function( elems ) {
31186  var items = this._itemize( elems );
31187  if ( !items.length ) {
31188    return;
31189  }
31190  // add items to beginning of collection
31191  var previousItems = this.items.slice(0);
31192  this.items = items.concat( previousItems );
31193  // start new layout
31194  this._resetLayout();
31195  this._manageStamps();
31196  // layout new stuff without transition
31197  this.layoutItems( items, true );
31198  this.reveal( items );
31199  // layout previous items
31200  this.layoutItems( previousItems );
31201};
31202
31203/**
31204 * reveal a collection of items
31205 * @param {Array of Outlayer.Items} items
31206 */
31207proto.reveal = function( items ) {
31208  this._emitCompleteOnItems( 'reveal', items );
31209  if ( !items || !items.length ) {
31210    return;
31211  }
31212  var stagger = this.updateStagger();
31213  items.forEach( function( item, i ) {
31214    item.stagger( i * stagger );
31215    item.reveal();
31216  });
31217};
31218
31219/**
31220 * hide a collection of items
31221 * @param {Array of Outlayer.Items} items
31222 */
31223proto.hide = function( items ) {
31224  this._emitCompleteOnItems( 'hide', items );
31225  if ( !items || !items.length ) {
31226    return;
31227  }
31228  var stagger = this.updateStagger();
31229  items.forEach( function( item, i ) {
31230    item.stagger( i * stagger );
31231    item.hide();
31232  });
31233};
31234
31235/**
31236 * reveal item elements
31237 * @param {Array}, {Element}, {NodeList} items
31238 */
31239proto.revealItemElements = function( elems ) {
31240  var items = this.getItems( elems );
31241  this.reveal( items );
31242};
31243
31244/**
31245 * hide item elements
31246 * @param {Array}, {Element}, {NodeList} items
31247 */
31248proto.hideItemElements = function( elems ) {
31249  var items = this.getItems( elems );
31250  this.hide( items );
31251};
31252
31253/**
31254 * get Outlayer.Item, given an Element
31255 * @param {Element} elem
31256 * @param {Function} callback
31257 * @returns {Outlayer.Item} item
31258 */
31259proto.getItem = function( elem ) {
31260  // loop through items to get the one that matches
31261  for ( var i=0; i < this.items.length; i++ ) {
31262    var item = this.items[i];
31263    if ( item.element == elem ) {
31264      // return item
31265      return item;
31266    }
31267  }
31268};
31269
31270/**
31271 * get collection of Outlayer.Items, given Elements
31272 * @param {Array} elems
31273 * @returns {Array} items - Outlayer.Items
31274 */
31275proto.getItems = function( elems ) {
31276  elems = utils.makeArray( elems );
31277  var items = [];
31278  elems.forEach( function( elem ) {
31279    var item = this.getItem( elem );
31280    if ( item ) {
31281      items.push( item );
31282    }
31283  }, this );
31284
31285  return items;
31286};
31287
31288/**
31289 * remove element(s) from instance and DOM
31290 * @param {Array or NodeList or Element} elems
31291 */
31292proto.remove = function( elems ) {
31293  var removeItems = this.getItems( elems );
31294
31295  this._emitCompleteOnItems( 'remove', removeItems );
31296
31297  // bail if no items to remove
31298  if ( !removeItems || !removeItems.length ) {
31299    return;
31300  }
31301
31302  removeItems.forEach( function( item ) {
31303    item.remove();
31304    // remove item from collection
31305    utils.removeFrom( this.items, item );
31306  }, this );
31307};
31308
31309// ----- destroy ----- //
31310
31311// remove and disable Outlayer instance
31312proto.destroy = function() {
31313  // clean up dynamic styles
31314  var style = this.element.style;
31315  style.height = '';
31316  style.position = '';
31317  style.width = '';
31318  // destroy items
31319  this.items.forEach( function( item ) {
31320    item.destroy();
31321  });
31322
31323  this.unbindResize();
31324
31325  var id = this.element.outlayerGUID;
31326  delete instances[ id ]; // remove reference to instance by id
31327  delete this.element.outlayerGUID;
31328  // remove data for jQuery
31329  if ( jQuery ) {
31330    jQuery.removeData( this.element, this.constructor.namespace );
31331  }
31332
31333};
31334
31335// -------------------------- data -------------------------- //
31336
31337/**
31338 * get Outlayer instance from element
31339 * @param {Element} elem
31340 * @returns {Outlayer}
31341 */
31342Outlayer.data = function( elem ) {
31343  elem = utils.getQueryElement( elem );
31344  var id = elem && elem.outlayerGUID;
31345  return id && instances[ id ];
31346};
31347
31348
31349// -------------------------- create Outlayer class -------------------------- //
31350
31351/**
31352 * create a layout class
31353 * @param {String} namespace
31354 */
31355Outlayer.create = function( namespace, options ) {
31356  // sub-class Outlayer
31357  var Layout = subclass( Outlayer );
31358  // apply new options and compatOptions
31359  Layout.defaults = utils.extend( {}, Outlayer.defaults );
31360  utils.extend( Layout.defaults, options );
31361  Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions  );
31362
31363  Layout.namespace = namespace;
31364
31365  Layout.data = Outlayer.data;
31366
31367  // sub-class Item
31368  Layout.Item = subclass( Item );
31369
31370  // -------------------------- declarative -------------------------- //
31371
31372  utils.htmlInit( Layout, namespace );
31373
31374  // -------------------------- jQuery bridge -------------------------- //
31375
31376  // make into jQuery plugin
31377  if ( jQuery && jQuery.bridget ) {
31378    jQuery.bridget( namespace, Layout );
31379  }
31380
31381  return Layout;
31382};
31383
31384function subclass( Parent ) {
31385  function SubClass() {
31386    Parent.apply( this, arguments );
31387  }
31388
31389  SubClass.prototype = Object.create( Parent.prototype );
31390  SubClass.prototype.constructor = SubClass;
31391
31392  return SubClass;
31393}
31394
31395// ----- helpers ----- //
31396
31397// how many milliseconds are in each unit
31398var msUnits = {
31399  ms: 1,
31400  s: 1000
31401};
31402
31403// munge time-like parameter into millisecond number
31404// '0.4s' -> 40
31405function getMilliseconds( time ) {
31406  if ( typeof time == 'number' ) {
31407    return time;
31408  }
31409  var matches = time.match( /(^\d*\.?\d*)(\w*)/ );
31410  var num = matches && matches[1];
31411  var unit = matches && matches[2];
31412  if ( !num.length ) {
31413    return 0;
31414  }
31415  num = parseFloat( num );
31416  var mult = msUnits[ unit ] || 1;
31417  return num * mult;
31418}
31419
31420// ----- fin ----- //
31421
31422// back in global
31423Outlayer.Item = Item;
31424
31425return Outlayer;
31426
31427}));
31428
vendor: 7,447 bytes, lines 31429-31713
31429
31430/***/ }),
31431/* 157 */
31432/***/ (function(module, exports, __webpack_require__) {
31433
31434var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
31435 * Fizzy UI utils v2.0.7
31436 * MIT license
31437 */
31438
31439/*jshint browser: true, undef: true, unused: true, strict: true */
31440
31441( function( window, factory ) {
31442  // universal module definition
31443  /*jshint strict: false */ /*globals define, module, require */
31444
31445  if ( true ) {
31446    // AMD
31447    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
31448      __webpack_require__(158)
31449    ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( matchesSelector ) {
31450      return factory( window, matchesSelector );
31451    }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
31452				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
31453  } else if ( typeof module == 'object' && module.exports ) {
31454    // CommonJS
31455    module.exports = factory(
31456      window,
31457      require('desandro-matches-selector')
31458    );
31459  } else {
31460    // browser global
31461    window.fizzyUIUtils = factory(
31462      window,
31463      window.matchesSelector
31464    );
31465  }
31466
31467}( window, function factory( window, matchesSelector ) {
31468
31469'use strict';
31470
31471var utils = {};
31472
31473// ----- extend ----- //
31474
31475// extends objects
31476utils.extend = function( a, b ) {
31477  for ( var prop in b ) {
31478    a[ prop ] = b[ prop ];
31479  }
31480  return a;
31481};
31482
31483// ----- modulo ----- //
31484
31485utils.modulo = function( num, div ) {
31486  return ( ( num % div ) + div ) % div;
31487};
31488
31489// ----- makeArray ----- //
31490
31491var arraySlice = Array.prototype.slice;
31492
31493// turn element or nodeList into an array
31494utils.makeArray = function( obj ) {
31495  if ( Array.isArray( obj ) ) {
31496    // use object if already an array
31497    return obj;
31498  }
31499  // return empty array if undefined or null. #6
31500  if ( obj === null || obj === undefined ) {
31501    return [];
31502  }
31503
31504  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
31505  if ( isArrayLike ) {
31506    // convert nodeList to array
31507    return arraySlice.call( obj );
31508  }
31509
31510  // array of single index
31511  return [ obj ];
31512};
31513
31514// ----- removeFrom ----- //
31515
31516utils.removeFrom = function( ary, obj ) {
31517  var index = ary.indexOf( obj );
31518  if ( index != -1 ) {
31519    ary.splice( index, 1 );
31520  }
31521};
31522
31523// ----- getParent ----- //
31524
31525utils.getParent = function( elem, selector ) {
31526  while ( elem.parentNode && elem != document.body ) {
31527    elem = elem.parentNode;
31528    if ( matchesSelector( elem, selector ) ) {
31529      return elem;
31530    }
31531  }
31532};
31533
31534// ----- getQueryElement ----- //
31535
31536// use element as selector string
31537utils.getQueryElement = function( elem ) {
31538  if ( typeof elem == 'string' ) {
31539    return document.querySelector( elem );
31540  }
31541  return elem;
31542};
31543
31544// ----- handleEvent ----- //
31545
31546// enable .ontype to trigger from .addEventListener( elem, 'type' )
31547utils.handleEvent = function( event ) {
31548  var method = 'on' + event.type;
31549  if ( this[ method ] ) {
31550    this[ method ]( event );
31551  }
31552};
31553
31554// ----- filterFindElements ----- //
31555
31556utils.filterFindElements = function( elems, selector ) {
31557  // make array of elems
31558  elems = utils.makeArray( elems );
31559  var ffElems = [];
31560
31561  elems.forEach( function( elem ) {
31562    // check that elem is an actual element
31563    if ( !( elem instanceof HTMLElement ) ) {
31564      return;
31565    }
31566    // add elem if no selector
31567    if ( !selector ) {
31568      ffElems.push( elem );
31569      return;
31570    }
31571    // filter & find items if we have a selector
31572    // filter
31573    if ( matchesSelector( elem, selector ) ) {
31574      ffElems.push( elem );
31575    }
31576    // find children
31577    var childElems = elem.querySelectorAll( selector );
31578    // concat childElems to filterFound array
31579    for ( var i=0; i < childElems.length; i++ ) {
31580      ffElems.push( childElems[i] );
31581    }
31582  });
31583
31584  return ffElems;
31585};
31586
31587// ----- debounceMethod ----- //
31588
31589utils.debounceMethod = function( _class, methodName, threshold ) {
31590  threshold = threshold || 100;
31591  // original method
31592  var method = _class.prototype[ methodName ];
31593  var timeoutName = methodName + 'Timeout';
31594
31595  _class.prototype[ methodName ] = function() {
31596    var timeout = this[ timeoutName ];
31597    clearTimeout( timeout );
31598
31599    var args = arguments;
31600    var _this = this;
31601    this[ timeoutName ] = setTimeout( function() {
31602      method.apply( _this, args );
31603      delete _this[ timeoutName ];
31604    }, threshold );
31605  };
31606};
31607
31608// ----- docReady ----- //
31609
31610utils.docReady = function( callback ) {
31611  var readyState = document.readyState;
31612  if ( readyState == 'complete' || readyState == 'interactive' ) {
31613    // do async to allow for other scripts to run. metafizzy/flickity#441
31614    setTimeout( callback );
31615  } else {
31616    document.addEventListener( 'DOMContentLoaded', callback );
31617  }
31618};
31619
31620// ----- htmlInit ----- //
31621
31622// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
31623utils.toDashed = function( str ) {
31624  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
31625    return $1 + '-' + $2;
31626  }).toLowerCase();
31627};
31628
31629var console = window.console;
31630/**
31631 * allow user to initialize classes via [data-namespace] or .js-namespace class
31632 * htmlInit( Widget, 'widgetName' )
31633 * options are parsed from data-namespace-options
31634 */
31635utils.htmlInit = function( WidgetClass, namespace ) {
31636  utils.docReady( function() {
31637    var dashedNamespace = utils.toDashed( namespace );
31638    var dataAttr = 'data-' + dashedNamespace;
31639    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
31640    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
31641    var elems = utils.makeArray( dataAttrElems )
31642      .concat( utils.makeArray( jsDashElems ) );
31643    var dataOptionsAttr = dataAttr + '-options';
31644    var jQuery = window.jQuery;
31645
31646    elems.forEach( function( elem ) {
31647      var attr = elem.getAttribute( dataAttr ) ||
31648        elem.getAttribute( dataOptionsAttr );
31649      var options;
31650      try {
31651        options = attr && JSON.parse( attr );
31652      } catch ( error ) {
31653        // log error, do not initialize
31654        if ( console ) {
31655          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
31656          ': ' + error );
31657        }
31658        return;
31659      }
31660      // initialize
31661      var instance = new WidgetClass( elem, options );
31662      // make available via $().data('namespace')
31663      if ( jQuery ) {
31664        jQuery.data( elem, namespace, instance );
31665      }
31666    });
31667
31668  });
31669};
31670
31671// -----  ----- //
31672
31673return utils;
31674
31675}));
31676
31677
31678/***/ }),
31679/* 158 */
31680/***/ (function(module, exports, __webpack_require__) {
31681
31682var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
31683 * matchesSelector v2.0.2
31684 * matchesSelector( element, '.selector' )
31685 * MIT license
31686 */
31687
31688/*jshint browser: true, strict: true, undef: true, unused: true */
31689
31690( function( window, factory ) {
31691  /*global define: false, module: false */
31692  'use strict';
31693  // universal module definition
31694  if ( true ) {
31695    // AMD
31696    !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
31697				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
31698				(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :
31699				__WEBPACK_AMD_DEFINE_FACTORY__),
31700				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
31701  } else if ( typeof module == 'object' && module.exports ) {
31702    // CommonJS
31703    module.exports = factory();
31704  } else {
31705    // browser global
31706    window.matchesSelector = factory();
31707  }
31708
31709}( window, function factory() {
31710  'use strict';
31711
31712  var matchesMethod = ( function() {
31713    var ElemProto = window.Element.prototype;
31714    // check for the standard method name first
31715    if ( ElemProto.matches ) {
31716      return 'matches';
31717    }
31718    // check un-prefixed
31719    if ( ElemProto.matchesSelector ) {
31720      return 'matchesSelector';
31721    }
31722    // check vendor prefixes
31723    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
31724
31725    for ( var i=0; i < prefixes.length; i++ ) {
31726      var prefix = prefixes[i];
31727      var method = prefix + 'MatchesSelector';
31728      if ( ElemProto[ method ] ) {
31729        return method;
31730      }
31731    }
31732  })();
31733
31734  return function matchesSelector( elem, selector ) {
31735    return elem[ matchesMethod ]( selector );
31736  };
31737
31738}));
31739
31740
31741/***/ }),
31742/* 159 */
31743/***/ (function(module, exports, __webpack_require__) {
31744
31745var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
31746 * Outlayer Item
31747 */
31748
31749( function( window, factory ) {
31750  // universal module definition
31751  /* jshint strict: false */ /* globals define, module, require */
31752  if ( true ) {
31753    // AMD - RequireJS
31754    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
31755        __webpack_require__(8),
31756        __webpack_require__(9)
31757      ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
31758				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
31759				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
31760				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)
vendor: 14,212 bytes, lines 31760-32300
31760);
31761  } else if ( typeof module == 'object' && module.exports ) {
31762    // CommonJS - Browserify, Webpack
31763    module.exports = factory(
31764      require('ev-emitter'),
31765      require('get-size')
31766    );
31767  } else {
31768    // browser global
31769    window.Outlayer = {};
31770    window.Outlayer.Item = factory(
31771      window.EvEmitter,
31772      window.getSize
31773    );
31774  }
31775
31776}( window, function factory( EvEmitter, getSize ) {
31777'use strict';
31778
31779// ----- helpers ----- //
31780
31781function isEmptyObj( obj ) {
31782  for ( var prop in obj ) {
31783    return false;
31784  }
31785  prop = null;
31786  return true;
31787}
31788
31789// -------------------------- CSS3 support -------------------------- //
31790
31791
31792var docElemStyle = document.documentElement.style;
31793
31794var transitionProperty = typeof docElemStyle.transition == 'string' ?
31795  'transition' : 'WebkitTransition';
31796var transformProperty = typeof docElemStyle.transform == 'string' ?
31797  'transform' : 'WebkitTransform';
31798
31799var transitionEndEvent = {
31800  WebkitTransition: 'webkitTransitionEnd',
31801  transition: 'transitionend'
31802}[ transitionProperty ];
31803
31804// cache all vendor properties that could have vendor prefix
31805var vendorProperties = {
31806  transform: transformProperty,
31807  transition: transitionProperty,
31808  transitionDuration: transitionProperty + 'Duration',
31809  transitionProperty: transitionProperty + 'Property',
31810  transitionDelay: transitionProperty + 'Delay'
31811};
31812
31813// -------------------------- Item -------------------------- //
31814
31815function Item( element, layout ) {
31816  if ( !element ) {
31817    return;
31818  }
31819
31820  this.element = element;
31821  // parent layout class, i.e. Masonry, Isotope, or Packery
31822  this.layout = layout;
31823  this.position = {
31824    x: 0,
31825    y: 0
31826  };
31827
31828  this._create();
31829}
31830
31831// inherit EvEmitter
31832var proto = Item.prototype = Object.create( EvEmitter.prototype );
31833proto.constructor = Item;
31834
31835proto._create = function() {
31836  // transition objects
31837  this._transn = {
31838    ingProperties: {},
31839    clean: {},
31840    onEnd: {}
31841  };
31842
31843  this.css({
31844    position: 'absolute'
31845  });
31846};
31847
31848// trigger specified handler for event type
31849proto.handleEvent = function( event ) {
31850  var method = 'on' + event.type;
31851  if ( this[ method ] ) {
31852    this[ method ]( event );
31853  }
31854};
31855
31856proto.getSize = function() {
31857  this.size = getSize( this.element );
31858};
31859
31860/**
31861 * apply CSS styles to element
31862 * @param {Object} style
31863 */
31864proto.css = function( style ) {
31865  var elemStyle = this.element.style;
31866
31867  for ( var prop in style ) {
31868    // use vendor property if available
31869    var supportedProp = vendorProperties[ prop ] || prop;
31870    elemStyle[ supportedProp ] = style[ prop ];
31871  }
31872};
31873
31874 // measure position, and sets it
31875proto.getPosition = function() {
31876  var style = getComputedStyle( this.element );
31877  var isOriginLeft = this.layout._getOption('originLeft');
31878  var isOriginTop = this.layout._getOption('originTop');
31879  var xValue = style[ isOriginLeft ? 'left' : 'right' ];
31880  var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
31881  var x = parseFloat( xValue );
31882  var y = parseFloat( yValue );
31883  // convert percent to pixels
31884  var layoutSize = this.layout.size;
31885  if ( xValue.indexOf('%') != -1 ) {
31886    x = ( x / 100 ) * layoutSize.width;
31887  }
31888  if ( yValue.indexOf('%') != -1 ) {
31889    y = ( y / 100 ) * layoutSize.height;
31890  }
31891  // clean up 'auto' or other non-integer values
31892  x = isNaN( x ) ? 0 : x;
31893  y = isNaN( y ) ? 0 : y;
31894  // remove padding from measurement
31895  x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
31896  y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
31897
31898  this.position.x = x;
31899  this.position.y = y;
31900};
31901
31902// set settled position, apply padding
31903proto.layoutPosition = function() {
31904  var layoutSize = this.layout.size;
31905  var style = {};
31906  var isOriginLeft = this.layout._getOption('originLeft');
31907  var isOriginTop = this.layout._getOption('originTop');
31908
31909  // x
31910  var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
31911  var xProperty = isOriginLeft ? 'left' : 'right';
31912  var xResetProperty = isOriginLeft ? 'right' : 'left';
31913
31914  var x = this.position.x + layoutSize[ xPadding ];
31915  // set in percentage or pixels
31916  style[ xProperty ] = this.getXValue( x );
31917  // reset other property
31918  style[ xResetProperty ] = '';
31919
31920  // y
31921  var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
31922  var yProperty = isOriginTop ? 'top' : 'bottom';
31923  var yResetProperty = isOriginTop ? 'bottom' : 'top';
31924
31925  var y = this.position.y + layoutSize[ yPadding ];
31926  // set in percentage or pixels
31927  style[ yProperty ] = this.getYValue( y );
31928  // reset other property
31929  style[ yResetProperty ] = '';
31930
31931  this.css( style );
31932  this.emitEvent( 'layout', [ this ] );
31933};
31934
31935proto.getXValue = function( x ) {
31936  var isHorizontal = this.layout._getOption('horizontal');
31937  return this.layout.options.percentPosition && !isHorizontal ?
31938    ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
31939};
31940
31941proto.getYValue = function( y ) {
31942  var isHorizontal = this.layout._getOption('horizontal');
31943  return this.layout.options.percentPosition && isHorizontal ?
31944    ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
31945};
31946
31947proto._transitionTo = function( x, y ) {
31948  this.getPosition();
31949  // get current x & y from top/left
31950  var curX = this.position.x;
31951  var curY = this.position.y;
31952
31953  var didNotMove = x == this.position.x && y == this.position.y;
31954
31955  // save end position
31956  this.setPosition( x, y );
31957
31958  // if did not move and not transitioning, just go to layout
31959  if ( didNotMove && !this.isTransitioning ) {
31960    this.layoutPosition();
31961    return;
31962  }
31963
31964  var transX = x - curX;
31965  var transY = y - curY;
31966  var transitionStyle = {};
31967  transitionStyle.transform = this.getTranslate( transX, transY );
31968
31969  this.transition({
31970    to: transitionStyle,
31971    onTransitionEnd: {
31972      transform: this.layoutPosition
31973    },
31974    isCleaning: true
31975  });
31976};
31977
31978proto.getTranslate = function( x, y ) {
31979  // flip cooridinates if origin on right or bottom
31980  var isOriginLeft = this.layout._getOption('originLeft');
31981  var isOriginTop = this.layout._getOption('originTop');
31982  x = isOriginLeft ? x : -x;
31983  y = isOriginTop ? y : -y;
31984  return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
31985};
31986
31987// non transition + transform support
31988proto.goTo = function( x, y ) {
31989  this.setPosition( x, y );
31990  this.layoutPosition();
31991};
31992
31993proto.moveTo = proto._transitionTo;
31994
31995proto.setPosition = function( x, y ) {
31996  this.position.x = parseFloat( x );
31997  this.position.y = parseFloat( y );
31998};
31999
32000// ----- transition ----- //
32001
32002/**
32003 * @param {Object} style - CSS
32004 * @param {Function} onTransitionEnd
32005 */
32006
32007// non transition, just trigger callback
32008proto._nonTransition = function( args ) {
32009  this.css( args.to );
32010  if ( args.isCleaning ) {
32011    this._removeStyles( args.to );
32012  }
32013  for ( var prop in args.onTransitionEnd ) {
32014    args.onTransitionEnd[ prop ].call( this );
32015  }
32016};
32017
32018/**
32019 * proper transition
32020 * @param {Object} args - arguments
32021 *   @param {Object} to - style to transition to
32022 *   @param {Object} from - style to start transition from
32023 *   @param {Boolean} isCleaning - removes transition styles after transition
32024 *   @param {Function} onTransitionEnd - callback
32025 */
32026proto.transition = function( args ) {
32027  // redirect to nonTransition if no transition duration
32028  if ( !parseFloat( this.layout.options.transitionDuration ) ) {
32029    this._nonTransition( args );
32030    return;
32031  }
32032
32033  var _transition = this._transn;
32034  // keep track of onTransitionEnd callback by css property
32035  for ( var prop in args.onTransitionEnd ) {
32036    _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
32037  }
32038  // keep track of properties that are transitioning
32039  for ( prop in args.to ) {
32040    _transition.ingProperties[ prop ] = true;
32041    // keep track of properties to clean up when transition is done
32042    if ( args.isCleaning ) {
32043      _transition.clean[ prop ] = true;
32044    }
32045  }
32046
32047  // set from styles
32048  if ( args.from ) {
32049    this.css( args.from );
32050    // force redraw. http://blog.alexmaccaw.com/css-transitions
32051    var h = this.element.offsetHeight;
32052    // hack for JSHint to hush about unused var
32053    h = null;
32054  }
32055  // enable transition
32056  this.enableTransition( args.to );
32057  // set styles that are transitioning
32058  this.css( args.to );
32059
32060  this.isTransitioning = true;
32061
32062};
32063
32064// dash before all cap letters, including first for
32065// WebkitTransform => -webkit-transform
32066function toDashedAll( str ) {
32067  return str.replace( /([A-Z])/g, function( $1 ) {
32068    return '-' + $1.toLowerCase();
32069  });
32070}
32071
32072var transitionProps = 'opacity,' + toDashedAll( transformProperty );
32073
32074proto.enableTransition = function(/* style */) {
32075  // HACK changing transitionProperty during a transition
32076  // will cause transition to jump
32077  if ( this.isTransitioning ) {
32078    return;
32079  }
32080
32081  // make `transition: foo, bar, baz` from style object
32082  // HACK un-comment this when enableTransition can work
32083  // while a transition is happening
32084  // var transitionValues = [];
32085  // for ( var prop in style ) {
32086  //   // dash-ify camelCased properties like WebkitTransition
32087  //   prop = vendorProperties[ prop ] || prop;
32088  //   transitionValues.push( toDashedAll( prop ) );
32089  // }
32090  // munge number to millisecond, to match stagger
32091  var duration = this.layout.options.transitionDuration;
32092  duration = typeof duration == 'number' ? duration + 'ms' : duration;
32093  // enable transition styles
32094  this.css({
32095    transitionProperty: transitionProps,
32096    transitionDuration: duration,
32097    transitionDelay: this.staggerDelay || 0
32098  });
32099  // listen for transition end event
32100  this.element.addEventListener( transitionEndEvent, this, false );
32101};
32102
32103// ----- events ----- //
32104
32105proto.onwebkitTransitionEnd = function( event ) {
32106  this.ontransitionend( event );
32107};
32108
32109proto.onotransitionend = function( event ) {
32110  this.ontransitionend( event );
32111};
32112
32113// properties that I munge to make my life easier
32114var dashedVendorProperties = {
32115  '-webkit-transform': 'transform'
32116};
32117
32118proto.ontransitionend = function( event ) {
32119  // disregard bubbled events from children
32120  if ( event.target !== this.element ) {
32121    return;
32122  }
32123  var _transition = this._transn;
32124  // get property name of transitioned property, convert to prefix-free
32125  var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
32126
32127  // remove property that has completed transitioning
32128  delete _transition.ingProperties[ propertyName ];
32129  // check if any properties are still transitioning
32130  if ( isEmptyObj( _transition.ingProperties ) ) {
32131    // all properties have completed transitioning
32132    this.disableTransition();
32133  }
32134  // clean style
32135  if ( propertyName in _transition.clean ) {
32136    // clean up style
32137    this.element.style[ event.propertyName ] = '';
32138    delete _transition.clean[ propertyName ];
32139  }
32140  // trigger onTransitionEnd callback
32141  if ( propertyName in _transition.onEnd ) {
32142    var onTransitionEnd = _transition.onEnd[ propertyName ];
32143    onTransitionEnd.call( this );
32144    delete _transition.onEnd[ propertyName ];
32145  }
32146
32147  this.emitEvent( 'transitionEnd', [ this ] );
32148};
32149
32150proto.disableTransition = function() {
32151  this.removeTransitionStyles();
32152  this.element.removeEventListener( transitionEndEvent, this, false );
32153  this.isTransitioning = false;
32154};
32155
32156/**
32157 * removes style property from element
32158 * @param {Object} style
32159**/
32160proto._removeStyles = function( style ) {
32161  // clean up transition styles
32162  var cleanStyle = {};
32163  for ( var prop in style ) {
32164    cleanStyle[ prop ] = '';
32165  }
32166  this.css( cleanStyle );
32167};
32168
32169var cleanTransitionStyle = {
32170  transitionProperty: '',
32171  transitionDuration: '',
32172  transitionDelay: ''
32173};
32174
32175proto.removeTransitionStyles = function() {
32176  // remove transition
32177  this.css( cleanTransitionStyle );
32178};
32179
32180// ----- stagger ----- //
32181
32182proto.stagger = function( delay ) {
32183  delay = isNaN( delay ) ? 0 : delay;
32184  this.staggerDelay = delay + 'ms';
32185};
32186
32187// ----- show/hide/remove ----- //
32188
32189// remove element from DOM
32190proto.removeElem = function() {
32191  this.element.parentNode.removeChild( this.element );
32192  // remove display: none
32193  this.css({ display: '' });
32194  this.emitEvent( 'remove', [ this ] );
32195};
32196
32197proto.remove = function() {
32198  // just remove element if no transition support or no transition
32199  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
32200    this.removeElem();
32201    return;
32202  }
32203
32204  // start transition
32205  this.once( 'transitionEnd', function() {
32206    this.removeElem();
32207  });
32208  this.hide();
32209};
32210
32211proto.reveal = function() {
32212  delete this.isHidden;
32213  // remove display: none
32214  this.css({ display: '' });
32215
32216  var options = this.layout.options;
32217
32218  var onTransitionEnd = {};
32219  var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
32220  onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;
32221
32222  this.transition({
32223    from: options.hiddenStyle,
32224    to: options.visibleStyle,
32225    isCleaning: true,
32226    onTransitionEnd: onTransitionEnd
32227  });
32228};
32229
32230proto.onRevealTransitionEnd = function() {
32231  // check if still visible
32232  // during transition, item may have been hidden
32233  if ( !this.isHidden ) {
32234    this.emitEvent('reveal');
32235  }
32236};
32237
32238/**
32239 * get style property use for hide/reveal transition end
32240 * @param {String} styleProperty - hiddenStyle/visibleStyle
32241 * @returns {String}
32242 */
32243proto.getHideRevealTransitionEndProperty = function( styleProperty ) {
32244  var optionStyle = this.layout.options[ styleProperty ];
32245  // use opacity
32246  if ( optionStyle.opacity ) {
32247    return 'opacity';
32248  }
32249  // get first property
32250  for ( var prop in optionStyle ) {
32251    return prop;
32252  }
32253};
32254
32255proto.hide = function() {
32256  // set flag
32257  this.isHidden = true;
32258  // remove display: none
32259  this.css({ display: '' });
32260
32261  var options = this.layout.options;
32262
32263  var onTransitionEnd = {};
32264  var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
32265  onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;
32266
32267  this.transition({
32268    from: options.visibleStyle,
32269    to: options.hiddenStyle,
32270    // keep hidden stuff hidden
32271    isCleaning: true,
32272    onTransitionEnd: onTransitionEnd
32273  });
32274};
32275
32276proto.onHideTransitionEnd = function() {
32277  // check if still hidden
32278  // during transition, item may have been un-hidden
32279  if ( this.isHidden ) {
32280    this.css({ display: 'none' });
32281    this.emitEvent('hide');
32282  }
32283};
32284
32285proto.destroy = function() {
32286  this.css({
32287    position: '',
32288    left: '',
32289    right: '',
32290    top: '',
32291    bottom: '',
32292    transition: '',
32293    transform: ''
32294  });
32295};
32296
32297return Item;
32298
32299}));
32300
32301
32302/***/ }),
32303/* 160 */
32304/***/ (function(module, exports) {
32305
32306module.exports = function(originalModule) {
32307	if(!originalModule.webpackPolyfill) {
32308		var module = Object.create(originalModule);
32309		// module.parent = undefined by default
32310		if(!module.children) module.children = [];
32311		Object.defineProperty(module, "loaded", {
32312			enumerable: true,
32313			get: function() {
32314				return module.l;
32315			}
32316		});
32317		Object.defineProperty(module, "id", {
32318			enumerable: true,
32319			get: function() {
32320				return module.i;
32321			}
32322		});
32323		Object.defineProperty(module, "exports", {
32324			enumerable: true,
32325		});
32326		module.webpackPolyfill = 1;
32327	}
32328	return module;
32329};
32330
32331
32332/***/ }),
32333/* 161 */
32334/***/ (function(module, exports, __webpack_require__) {
32335
32336var map = {
32337	"./af": 10,
32338	"./af.js": 10,
32339	"./ar": 11,
32340	"./ar-dz": 12,
32341	"./ar-dz.js": 12,
32342	"./ar-kw": 13,
32343	"./ar-kw.js": 13,
32344	"./ar-ly": 14,
32345	"./ar-ly.js": 14,
32346	"./ar-ma": 15,
32347	"./ar-ma.js": 15,
32348	"./ar-sa": 16,
32349	"./ar-sa.js": 16,
32350	"./ar-tn": 17,
32351	"./ar-tn.js": 17,
32352	"./ar.js": 11,
32353	"./az": 18,
32354	"./az.js": 18,
32355	"./be": 19,
32356	"./be.js": 19,
32357	"./bg": 20,
32358	"./bg.js": 20,
32359	"./bm": 21,
32360	"./bm.js": 21,
32361	"./bn": 22,
32362	"./bn-bd": 23,
32363	"./bn-bd.js": 23,
32364	"./bn.js": 22,
32365	"./bo": 24,
32366	"./bo.js": 24,
32367	"./br": 25,
32368	"./br.js": 25,
32369	"./bs": 26,
32370	"./bs.js": 26,
32371	"./ca": 27,
32372	"./ca.js": 27,
32373	"./cs": 28,
32374	"./cs.js": 28,
32375	"./cv": 29,
32376	"./cv.js": 29,
32377	"./cy": 30,
32378	"./cy.js": 30,
32379	"./da": 31,
32380	"./da.js": 31,
32381	"./de": 32,
32382	"./de-at": 33,
32383	"./de-at.js": 33,
32384	"./de-ch": 34,
32385	"./de-ch.js": 34,
32386	"./de.js": 32,
32387	"./dv": 35,
32388	"./dv.js": 35,
32389	"./el": 36,
32390	"./el.js": 36,
32391	"./en-au": 37,
32392	"./en-au.js": 37,
32393	"./en-ca": 38,
32394	"./en-ca.js": 38,
32395	"./en-gb": 39,
32396	"./en-gb.js": 39,
32397	"./en-ie": 40,
32398	"./en-ie.js": 40,
32399	"./en-il": 41,
32400	"./en-il.js": 41,
32401	"./en-in": 42,
32402	"./en-in.js": 42,
32403	"./en-nz": 43,
32404	"./en-nz.js": 43,
32405	"./en-sg": 44,
32406	"./en-sg.js": 44,
32407	"./eo": 45,
32408	"./eo.js": 45,
32409	"./es": 46,
32410	"./es-do": 47,
32411	"./es-do.js": 47,
32412	"./es-mx": 48,
32413	"./es-mx.js": 48,
32414	"./es-us": 49,
32415	"./es-us.js": 49,
32416	"./es.js": 46,
32417	"./et": 50,
32418	"./et.js": 50,
32419	"./eu": 51,
32420	"./eu.js": 51,
32421	"./fa": 52,
32422	"./fa.js": 52,
32423	"./fi": 53,
32424	"./fi.js": 53,
32425	"./fil": 54,
32426	"./fil.js": 54,
32427	"./fo": 55,
32428	"./fo.js": 55,
32429	"./fr": 56,
32430	"./fr-ca": 57,
32431	"./fr-ca.js": 57,
32432	"./fr-ch": 58,
32433	"./fr-ch.js": 58,
32434	"./fr.js": 56,
32435	"./fy": 59,
32436	"./fy.js": 59,
32437	"./ga": 60,
32438	"./ga.js": 60,
32439	"./gd": 61,
32440	"./gd.js": 61,
32441	"./gl": 62,
32442	"./gl.js": 62,
32443	"./gom-deva": 63,
32444	"./gom-deva.js": 63,
32445	"./gom-latn": 64,
32446	"./gom-latn.js": 64,
32447	"./gu": 65,
32448	"./gu.js": 65,
32449	"./he": 66,
32450	"./he.js": 66,
32451	"./hi": 67,
32452	"./hi.js": 67,
32453	"./hr": 68,
32454	"./hr.js": 68,
32455	"./hu": 69,
32456	"./hu.js": 69,
32457	"./hy-am": 70,
32458	"./hy-am.js": 70,
32459	"./id": 71,
32460	"./id.js": 71,
32461	"./is": 72,
32462	"./is.js": 72,
32463	"./it": 73,
32464	"./it-ch": 74,
32465	"./it-ch.js": 74,
32466	"./it.js": 73,
32467	"./ja": 75,
32468	"./ja.js": 75,
32469	"./jv": 76,
32470	"./jv.js": 76,
32471	"./ka": 77,
32472	"./ka.js": 77,
32473	"./kk": 78,
32474	"./kk.js": 78,
32475	"./km": 79,
32476	"./km.js": 79,
32477	"./kn": 80,
32478	"./kn.js": 80,
32479	"./ko": 81,
32480	"./ko.js": 81,
32481	"./ku": 82,
32482	"./ku.js": 82,
32483	"./ky": 83,
32484	"./ky.js": 83,
32485	"./lb": 84,
32486	"./lb.js": 84,
32487	"./lo": 85,
32488	"./lo.js": 85,
32489	"./lt": 86,
32490	"./lt.js": 86,
32491	"./lv": 87,
32492	"./lv.js": 87,
32493	"./me": 88,
32494	"./me.js": 88,
32495	"./mi": 89,
32496	"./mi.js": 89,
32497	"./mk": 90,
32498	"./mk.js": 90,
32499	"./ml": 91,
32500	"./ml.js": 91,
32501	"./mn": 92,
32502	"./mn.js": 92,
32503	"./mr": 93,
32504	"./mr.js": 93,
32505	"./ms": 94,
32506	"./ms-my": 95,
32507	"./ms-my.js": 95,
32508	"./ms.js": 94,
32509	"./mt": 96,
32510	"./mt.js": 96,
32511	"./my": 97,
32512	"./my.js": 97,
32513	"./nb": 98,
32514	"./nb.js": 98,
32515	"./ne": 99,
32516	"./ne.js": 99,
32517	"./nl": 100,
32518	"./nl-be": 101,
32519	"./nl-be.js": 101,
32520	"./nl.js": 100,
32521	"./nn": 102,
32522	"./nn.js": 102,
32523	"./oc-lnc": 103,
32524	"./oc-lnc.js": 103,
32525	"./pa-in": 104,
32526	"./pa-in.js": 104,
32527	"./pl": 105,
32528	"./pl.js": 105,
32529	"./pt": 106,
32530	"./pt-br": 107,
32531	"./pt-br.js": 107,
32532	"./pt.js": 106,
32533	"./ro": 108,
32534	"./ro.js": 108,
32535	"./ru": 109,
32536	"./ru.js": 109,
32537	"./sd": 110,
32538	"./sd.js": 110,
32539	"./se": 111,
32540	"./se.js": 111,
32541	"./si": 112,
32542	"./si.js": 112,
32543	"./sk": 113,
32544	"./sk.js": 113,
32545	"./sl": 114,
32546	"./sl.js": 114,
32547	"./sq": 115,
32548	"./sq.js": 115,
32549	"./sr": 116,
32550	"./sr-cyrl": 117,
32551	"./sr-cyrl.js": 117,
32552	"./sr.js": 116,
32553	"./ss": 118,
32554	"./ss.js": 118,
32555	"./sv": 119,
32556	"./sv.js": 119,
32557	"./sw": 120,
32558	"./sw.js": 120,
32559	"./ta": 121,
32560	"./ta.js": 121,
32561	"./te": 122,
32562	"./te.js": 122,
32563	"./tet": 123,
32564	"./tet.js": 123,
32565	"./tg": 124,
32566	"./tg.js": 124,
32567	"./th": 125,
32568	"./th.js": 125,
32569	"./tk": 126,
32570	"./tk.js": 126,
32571	"./tl-ph": 127,
32572	"./tl-ph.js": 127,
32573	"./tlh": 128,
32574	"./tlh.js": 128,
32575	"./tr": 129,
32576	"./tr.js": 129,
32577	"./tzl": 130,
32578	"./tzl.js": 130,
32579	"./tzm": 131,
32580	"./tzm-latn": 132,
32581	"./tzm-latn.js": 132,
32582	"./tzm.js": 131,
32583	"./ug-cn": 133,
32584	"./ug-cn.js": 133,
32585	"./uk": 134,
32586	"./uk.js": 134,
32587	"./ur": 135,
32588	"./ur.js": 135,
32589	"./uz": 136,
32590	"./uz-latn": 137,
32591	"./uz-latn.js": 137,
32592	"./uz.js": 136,
32593	"./vi": 138,
32594	"./vi.js": 138,
32595	"./x-pseudo": 139,
32596	"./x-pseudo.js": 139,
32597	"./yo": 140,
32598	"./yo.js": 140,
32599	"./zh-cn": 141,
32600	"./zh-cn.js": 141,
32601	"./zh-hk": 142,
32602	"./zh-hk.js": 142,
32603	"./zh-mo": 143,
32604	"./zh-mo.js": 143,
32605	"./zh-tw": 144,
32606	"./zh-tw.js": 144
32607};
32608function webpackContext(req) {
32609	return __webpack_require__(webpackContextResolve(req));
32610};
32611function webpackContextResolve(req) {
32612	var id = map[req];
32613	if(!(id + 1)) // check for number or string
32614		throw new Error("Cannot find module '" + req + "'.");
32615	return id;
32616};
32617webpackContext.keys = function webpackContextKeys() {
32618	return Object.keys(map);
32619};
32620webpackContext.resolve = webpackContextResolve;
32621module.exports = webpackContext;
32622webpackContext.id = 161;
32623
32624/***/ }),
32625/* 162 */
32626/***/ (function(module, exports, __webpack_require__) {
32627
32628var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* eslint-disable max-len, camelcase */
32629/*!
32630 * jQuery UI Datepicker 1.13.0
32631 * http://jqueryui.com
32632 *
32633 * Copyright jQuery Foundation and other contributors
32634 * Released under the MIT license.
32635 * http://jquery.org/license
32636 */
32637
32638//>>label: Datepicker
32639//>>group: Widgets
32640//>>description: Displays a calendar from an input or inline for selecting dates.
32641//>>docs: http://api.jqueryui.com/datepicker/
32642//>>demos: http://jqueryui.com/datepicker/
32643//>>css.structure: ../../themes/base/core.css
32644//>>css.structure: ../../themes/base/datepicker.css
32645//>>css.theme: ../../themes/base/theme.css
32646
32647( function( factory ) {
32648	"use strict";
32649
32650	if ( true ) {
32651
32652		// AMD. Register as an anonymous module.
32653		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
32654			__webpack_require__(2),
32655			__webpack_require__(5),
32656			__webpack_require__(163)
32657		], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
32658				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
32659				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
32660				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
32661	} else {
32662
32663		// Browser globals
32664		factory( jQuery );
32665	}
32666} )( function( $ ) {
32667"use strict";
32668
32669$.extend( $.ui, { datepicker: { version: "1.13.0
vendor: 14,162 bytes, lines 32669-32986
32669" } } );
32670
32671var datepicker_instActive;
32672
32673function datepicker_getZindex( elem ) {
32674	var position, value;
32675	while ( elem.length && elem[ 0 ] !== document ) {
32676
32677		// Ignore z-index if position is set to a value where z-index is ignored by the browser
32678		// This makes behavior of this function consistent across browsers
32679		// WebKit always returns auto if the element is positioned
32680		position = elem.css( "position" );
32681		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
32682
32683			// IE returns 0 when zIndex is not specified
32684			// other browsers return a string
32685			// we ignore the case of nested elements with an explicit value of 0
32686			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
32687			value = parseInt( elem.css( "zIndex" ), 10 );
32688			if ( !isNaN( value ) && value !== 0 ) {
32689				return value;
32690			}
32691		}
32692		elem = elem.parent();
32693	}
32694
32695	return 0;
32696}
32697
32698/* Date picker manager.
32699   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
32700   Settings for (groups of) date pickers are maintained in an instance object,
32701   allowing multiple different settings on the same page. */
32702
32703function Datepicker() {
32704	this._curInst = null; // The current instance in use
32705	this._keyEvent = false; // If the last event was a key event
32706	this._disabledInputs = []; // List of date picker inputs that have been disabled
32707	this._datepickerShowing = false; // True if the popup picker is showing , false if not
32708	this._inDialog = false; // True if showing within a "dialog", false if not
32709	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
32710	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
32711	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
32712	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
32713	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
32714	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
32715	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
32716	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
32717	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
32718	this.regional = []; // Available regional settings, indexed by language code
32719	this.regional[ "" ] = { // Default regional settings
32720		closeText: "Done", // Display text for close link
32721		prevText: "Prev", // Display text for previous month link
32722		nextText: "Next", // Display text for next month link
32723		currentText: "Today", // Display text for current month link
32724		monthNames: [ "January", "February", "March", "April", "May", "June",
32725			"July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting
32726		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
32727		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
32728		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
32729		dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday
32730		weekHeader: "Wk", // Column header for week of the year
32731		dateFormat: "mm/dd/yy", // See format options on parseDate
32732		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
32733		isRTL: false, // True if right-to-left language, false if left-to-right
32734		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
32735		yearSuffix: "", // Additional text to append to the year in the month headers,
32736		selectMonthLabel: "Select month", // Invisible label for month selector
32737		selectYearLabel: "Select year" // Invisible label for year selector
32738	};
32739	this._defaults = { // Global defaults for all the date picker instances
32740		showOn: "focus", // "focus" for popup on focus,
32741			// "button" for trigger button, or "both" for either
32742		showAnim: "fadeIn", // Name of jQuery animation for popup
32743		showOptions: {}, // Options for enhanced animations
32744		defaultDate: null, // Used when field is blank: actual date,
32745			// +/-number for offset from today, null for today
32746		appendText: "", // Display text following the input box, e.g. showing the format
32747		buttonText: "...", // Text for trigger button
32748		buttonImage: "", // URL for trigger button image
32749		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
32750		hideIfNoPrevNext: false, // True to hide next/previous month links
32751			// if not applicable, false to just disable them
32752		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
32753		gotoCurrent: false, // True if today link goes back to current selection instead
32754		changeMonth: false, // True if month can be selected directly, false if only prev/next
32755		changeYear: false, // True if year can be selected directly, false if only prev/next
32756		yearRange: "c-10:c+10", // Range of years to display in drop-down,
32757			// either relative to today's year (-nn:+nn), relative to currently displayed year
32758			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
32759		showOtherMonths: false, // True to show dates in other months, false to leave blank
32760		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
32761		showWeek: false, // True to show week of the year, false to not show it
32762		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
32763			// takes a Date and returns the number of the week for it
32764		shortYearCutoff: "+10", // Short year values < this are in the current century,
32765			// > this are in the previous century,
32766			// string value starting with "+" for current year + value
32767		minDate: null, // The earliest selectable date, or null for no limit
32768		maxDate: null, // The latest selectable date, or null for no limit
32769		duration: "fast", // Duration of display/closure
32770		beforeShowDay: null, // Function that takes a date and returns an array with
32771			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
32772			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
32773		beforeShow: null, // Function that takes an input field and
32774			// returns a set of custom settings for the date picker
32775		onSelect: null, // Define a callback function when a date is selected
32776		onChangeMonthYear: null, // Define a callback function when the month or year is changed
32777		onClose: null, // Define a callback function when the datepicker is closed
32778		onUpdateDatepicker: null, // Define a callback function when the datepicker is updated
32779		numberOfMonths: 1, // Number of months to show at a time
32780		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
32781		stepMonths: 1, // Number of months to step back/forward
32782		stepBigMonths: 12, // Number of months to step back/forward for the big links
32783		altField: "", // Selector for an alternate field to store selected dates into
32784		altFormat: "", // The date format to use for the alternate field
32785		constrainInput: true, // The input is constrained by the current date format
32786		showButtonPanel: false, // True to show button panel, false to not show it
32787		autoSize: false, // True to size the input for the date format, false to leave as is
32788		disabled: false // The initial disabled state
32789	};
32790	$.extend( this._defaults, this.regional[ "" ] );
32791	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
32792	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
32793	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
32794}
32795
32796$.extend( Datepicker.prototype, {
32797
32798	/* Class name added to elements to indicate already configured with a date picker. */
32799	markerClassName: "hasDatepicker",
32800
32801	//Keep track of the maximum number of rows displayed (see #7043)
32802	maxRows: 4,
32803
32804	// TODO rename to "widget" when switching to widget factory
32805	_widgetDatepicker: function() {
32806		return this.dpDiv;
32807	},
32808
32809	/* Override the default settings for all instances of the date picker.
32810	 * @param  settings  object - the new settings to use as defaults (anonymous object)
32811	 * @return the manager object
32812	 */
32813	setDefaults: function( settings ) {
32814		datepicker_extendRemove( this._defaults, settings || {} );
32815		return this;
32816	},
32817
32818	/* Attach the date picker to a jQuery selection.
32819	 * @param  target	element - the target input field or division or span
32820	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
32821	 */
32822	_attachDatepicker: function( target, settings ) {
32823		var nodeName, inline, inst;
32824		nodeName = target.nodeName.toLowerCase();
32825		inline = ( nodeName === "div" || nodeName === "span" );
32826		if ( !target.id ) {
32827			this.uuid += 1;
32828			target.id = "dp" + this.uuid;
32829		}
32830		inst = this._newInst( $( target ), inline );
32831		inst.settings = $.extend( {}, settings || {} );
32832		if ( nodeName === "input" ) {
32833			this._connectDatepicker( target, inst );
32834		} else if ( inline ) {
32835			this._inlineDatepicker( target, inst );
32836		}
32837	},
32838
32839	/* Create a new instance object. */
32840	_newInst: function( target, inline ) {
32841		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
32842		return { id: id, input: target, // associated target
32843			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
32844			drawMonth: 0, drawYear: 0, // month being drawn
32845			inline: inline, // is datepicker inline or not
32846			dpDiv: ( !inline ? this.dpDiv : // presentation div
32847			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
32848	},
32849
32850	/* Attach the date picker to an input field. */
32851	_connectDatepicker: function( target, inst ) {
32852		var input = $( target );
32853		inst.append = $( [] );
32854		inst.trigger = $( [] );
32855		if ( input.hasClass( this.markerClassName ) ) {
32856			return;
32857		}
32858		this._attachments( input, inst );
32859		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
32860			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
32861		this._autoSize( inst );
32862		$.data( target, "datepicker", inst );
32863
32864		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
32865		if ( inst.settings.disabled ) {
32866			this._disableDatepicker( target );
32867		}
32868	},
32869
32870	/* Make attachments based on settings. */
32871	_attachments: function( input, inst ) {
32872		var showOn, buttonText, buttonImage,
32873			appendText = this._get( inst, "appendText" ),
32874			isRTL = this._get( inst, "isRTL" );
32875
32876		if ( inst.append ) {
32877			inst.append.remove();
32878		}
32879		if ( appendText ) {
32880			inst.append = $( "<span>" )
32881				.addClass( this._appendClass )
32882				.text( appendText );
32883			input[ isRTL ? "before" : "after" ]( inst.append );
32884		}
32885
32886		input.off( "focus", this._showDatepicker );
32887
32888		if ( inst.trigger ) {
32889			inst.trigger.remove();
32890		}
32891
32892		showOn = this._get( inst, "showOn" );
32893		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
32894			input.on( "focus", this._showDatepicker );
32895		}
32896		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
32897			buttonText = this._get( inst, "buttonText" );
32898			buttonImage = this._get( inst, "buttonImage" );
32899
32900			if ( this._get( inst, "buttonImageOnly" ) ) {
32901				inst.trigger = $( "<img>" )
32902					.addClass( this._triggerClass )
32903					.attr( {
32904						src: buttonImage,
32905						alt: buttonText,
32906						title: buttonText
32907					} );
32908			} else {
32909				inst.trigger = $( "<button type='button'>" )
32910					.addClass( this._triggerClass );
32911				if ( buttonImage ) {
32912					inst.trigger.html(
32913						$( "<img>" )
32914							.attr( {
32915								src: buttonImage,
32916								alt: buttonText,
32917								title: buttonText
32918							} )
32919					);
32920				} else {
32921					inst.trigger.text( buttonText );
32922				}
32923			}
32924
32925			input[ isRTL ? "before" : "after" ]( inst.trigger );
32926			inst.trigger.on( "click", function() {
32927				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
32928					$.datepicker._hideDatepicker();
32929				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
32930					$.datepicker._hideDatepicker();
32931					$.datepicker._showDatepicker( input[ 0 ] );
32932				} else {
32933					$.datepicker._showDatepicker( input[ 0 ] );
32934				}
32935				return false;
32936			} );
32937		}
32938	},
32939
32940	/* Apply the maximum length for the date format. */
32941	_autoSize: function( inst ) {
32942		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
32943			var findMax, max, maxI, i,
32944				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
32945				dateFormat = this._get( inst, "dateFormat" );
32946
32947			if ( dateFormat.match( /[DM]/ ) ) {
32948				findMax = function( names ) {
32949					max = 0;
32950					maxI = 0;
32951					for ( i = 0; i < names.length; i++ ) {
32952						if ( names[ i ].length > max ) {
32953							max = names[ i ].length;
32954							maxI = i;
32955						}
32956					}
32957					return maxI;
32958				};
32959				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
32960					"monthNames" : "monthNamesShort" ) ) ) );
32961				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
32962					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
32963			}
32964			inst.input.attr( "size", this._formatDate( inst, date ).length );
32965		}
32966	},
32967
32968	/* Attach an inline date picker to a div. */
32969	_inlineDatepicker: function( target, inst ) {
32970		var divSpan = $( target );
32971		if ( divSpan.hasClass( this.markerClassName ) ) {
32972			return;
32973		}
32974		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
32975		$.data( target, "datepicker", inst );
32976		this._setDate( inst, this._getDefaultDate( inst ), true );
32977		this._updateDatepicker( inst );
32978		this._updateAlternate( inst );
32979
32980		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
32981		if ( inst.settings.disabled ) {
32982			this._disableDatepicker( target );
32983		}
32984
32985		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
32986		// http
vendor: 14,693 bytes, lines 32986-33408
32986://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
32987		inst.dpDiv.css( "display", "block" );
32988	},
32989
32990	/* Pop-up the date picker in a "dialog" box.
32991	 * @param  input element - ignored
32992	 * @param  date	string or Date - the initial date to display
32993	 * @param  onSelect  function - the function to call when a date is selected
32994	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
32995	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
32996	 *					event - with x/y coordinates or
32997	 *					leave empty for default (screen centre)
32998	 * @return the manager object
32999	 */
33000	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
33001		var id, browserWidth, browserHeight, scrollX, scrollY,
33002			inst = this._dialogInst; // internal instance
33003
33004		if ( !inst ) {
33005			this.uuid += 1;
33006			id = "dp" + this.uuid;
33007			this._dialogInput = $( "<input type='text' id='" + id +
33008				"' style='position: absolute; top: -100px; width: 0px;'/>" );
33009			this._dialogInput.on( "keydown", this._doKeyDown );
33010			$( "body" ).append( this._dialogInput );
33011			inst = this._dialogInst = this._newInst( this._dialogInput, false );
33012			inst.settings = {};
33013			$.data( this._dialogInput[ 0 ], "datepicker", inst );
33014		}
33015		datepicker_extendRemove( inst.settings, settings || {} );
33016		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
33017		this._dialogInput.val( date );
33018
33019		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
33020		if ( !this._pos ) {
33021			browserWidth = document.documentElement.clientWidth;
33022			browserHeight = document.documentElement.clientHeight;
33023			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
33024			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
33025			this._pos = // should use actual width/height below
33026				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
33027		}
33028
33029		// Move input on screen for focus, but hidden behind dialog
33030		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
33031		inst.settings.onSelect = onSelect;
33032		this._inDialog = true;
33033		this.dpDiv.addClass( this._dialogClass );
33034		this._showDatepicker( this._dialogInput[ 0 ] );
33035		if ( $.blockUI ) {
33036			$.blockUI( this.dpDiv );
33037		}
33038		$.data( this._dialogInput[ 0 ], "datepicker", inst );
33039		return this;
33040	},
33041
33042	/* Detach a datepicker from its control.
33043	 * @param  target	element - the target input field or division or span
33044	 */
33045	_destroyDatepicker: function( target ) {
33046		var nodeName,
33047			$target = $( target ),
33048			inst = $.data( target, "datepicker" );
33049
33050		if ( !$target.hasClass( this.markerClassName ) ) {
33051			return;
33052		}
33053
33054		nodeName = target.nodeName.toLowerCase();
33055		$.removeData( target, "datepicker" );
33056		if ( nodeName === "input" ) {
33057			inst.append.remove();
33058			inst.trigger.remove();
33059			$target.removeClass( this.markerClassName ).
33060				off( "focus", this._showDatepicker ).
33061				off( "keydown", this._doKeyDown ).
33062				off( "keypress", this._doKeyPress ).
33063				off( "keyup", this._doKeyUp );
33064		} else if ( nodeName === "div" || nodeName === "span" ) {
33065			$target.removeClass( this.markerClassName ).empty();
33066		}
33067
33068		if ( datepicker_instActive === inst ) {
33069			datepicker_instActive = null;
33070			this._curInst = null;
33071		}
33072	},
33073
33074	/* Enable the date picker to a jQuery selection.
33075	 * @param  target	element - the target input field or division or span
33076	 */
33077	_enableDatepicker: function( target ) {
33078		var nodeName, inline,
33079			$target = $( target ),
33080			inst = $.data( target, "datepicker" );
33081
33082		if ( !$target.hasClass( this.markerClassName ) ) {
33083			return;
33084		}
33085
33086		nodeName = target.nodeName.toLowerCase();
33087		if ( nodeName === "input" ) {
33088			target.disabled = false;
33089			inst.trigger.filter( "button" ).
33090				each( function() {
33091					this.disabled = false;
33092				} ).end().
33093				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
33094		} else if ( nodeName === "div" || nodeName === "span" ) {
33095			inline = $target.children( "." + this._inlineClass );
33096			inline.children().removeClass( "ui-state-disabled" );
33097			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
33098				prop( "disabled", false );
33099		}
33100		this._disabledInputs = $.map( this._disabledInputs,
33101
33102			// Delete entry
33103			function( value ) {
33104				return ( value === target ? null : value );
33105			} );
33106	},
33107
33108	/* Disable the date picker to a jQuery selection.
33109	 * @param  target	element - the target input field or division or span
33110	 */
33111	_disableDatepicker: function( target ) {
33112		var nodeName, inline,
33113			$target = $( target ),
33114			inst = $.data( target, "datepicker" );
33115
33116		if ( !$target.hasClass( this.markerClassName ) ) {
33117			return;
33118		}
33119
33120		nodeName = target.nodeName.toLowerCase();
33121		if ( nodeName === "input" ) {
33122			target.disabled = true;
33123			inst.trigger.filter( "button" ).
33124				each( function() {
33125					this.disabled = true;
33126				} ).end().
33127				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
33128		} else if ( nodeName === "div" || nodeName === "span" ) {
33129			inline = $target.children( "." + this._inlineClass );
33130			inline.children().addClass( "ui-state-disabled" );
33131			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
33132				prop( "disabled", true );
33133		}
33134		this._disabledInputs = $.map( this._disabledInputs,
33135
33136			// Delete entry
33137			function( value ) {
33138				return ( value === target ? null : value );
33139			} );
33140		this._disabledInputs[ this._disabledInputs.length ] = target;
33141	},
33142
33143	/* Is the first field in a jQuery collection disabled as a datepicker?
33144	 * @param  target	element - the target input field or division or span
33145	 * @return boolean - true if disabled, false if enabled
33146	 */
33147	_isDisabledDatepicker: function( target ) {
33148		if ( !target ) {
33149			return false;
33150		}
33151		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
33152			if ( this._disabledInputs[ i ] === target ) {
33153				return true;
33154			}
33155		}
33156		return false;
33157	},
33158
33159	/* Retrieve the instance data for the target control.
33160	 * @param  target  element - the target input field or division or span
33161	 * @return  object - the associated instance data
33162	 * @throws  error if a jQuery problem getting data
33163	 */
33164	_getInst: function( target ) {
33165		try {
33166			return $.data( target, "datepicker" );
33167		} catch ( err ) {
33168			throw "Missing instance data for this datepicker";
33169		}
33170	},
33171
33172	/* Update or retrieve the settings for a date picker attached to an input field or division.
33173	 * @param  target  element - the target input field or division or span
33174	 * @param  name	object - the new settings to update or
33175	 *				string - the name of the setting to change or retrieve,
33176	 *				when retrieving also "all" for all instance settings or
33177	 *				"defaults" for all global defaults
33178	 * @param  value   any - the new value for the setting
33179	 *				(omit if above is an object or to retrieve a value)
33180	 */
33181	_optionDatepicker: function( target, name, value ) {
33182		var settings, date, minDate, maxDate,
33183			inst = this._getInst( target );
33184
33185		if ( arguments.length === 2 && typeof name === "string" ) {
33186			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
33187				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
33188				this._get( inst, name ) ) : null ) );
33189		}
33190
33191		settings = name || {};
33192		if ( typeof name === "string" ) {
33193			settings = {};
33194			settings[ name ] = value;
33195		}
33196
33197		if ( inst ) {
33198			if ( this._curInst === inst ) {
33199				this._hideDatepicker();
33200			}
33201
33202			date = this._getDateDatepicker( target, true );
33203			minDate = this._getMinMaxDate( inst, "min" );
33204			maxDate = this._getMinMaxDate( inst, "max" );
33205			datepicker_extendRemove( inst.settings, settings );
33206
33207			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
33208			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
33209				inst.settings.minDate = this._formatDate( inst, minDate );
33210			}
33211			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
33212				inst.settings.maxDate = this._formatDate( inst, maxDate );
33213			}
33214			if ( "disabled" in settings ) {
33215				if ( settings.disabled ) {
33216					this._disableDatepicker( target );
33217				} else {
33218					this._enableDatepicker( target );
33219				}
33220			}
33221			this._attachments( $( target ), inst );
33222			this._autoSize( inst );
33223			this._setDate( inst, date );
33224			this._updateAlternate( inst );
33225			this._updateDatepicker( inst );
33226		}
33227	},
33228
33229	// Change method deprecated
33230	_changeDatepicker: function( target, name, value ) {
33231		this._optionDatepicker( target, name, value );
33232	},
33233
33234	/* Redraw the date picker attached to an input field or division.
33235	 * @param  target  element - the target input field or division or span
33236	 */
33237	_refreshDatepicker: function( target ) {
33238		var inst = this._getInst( target );
33239		if ( inst ) {
33240			this._updateDatepicker( inst );
33241		}
33242	},
33243
33244	/* Set the dates for a jQuery selection.
33245	 * @param  target element - the target input field or division or span
33246	 * @param  date	Date - the new date
33247	 */
33248	_setDateDatepicker: function( target, date ) {
33249		var inst = this._getInst( target );
33250		if ( inst ) {
33251			this._setDate( inst, date );
33252			this._updateDatepicker( inst );
33253			this._updateAlternate( inst );
33254		}
33255	},
33256
33257	/* Get the date(s) for the first entry in a jQuery selection.
33258	 * @param  target element - the target input field or division or span
33259	 * @param  noDefault boolean - true if no default date is to be used
33260	 * @return Date - the current date
33261	 */
33262	_getDateDatepicker: function( target, noDefault ) {
33263		var inst = this._getInst( target );
33264		if ( inst && !inst.inline ) {
33265			this._setDateFromField( inst, noDefault );
33266		}
33267		return ( inst ? this._getDate( inst ) : null );
33268	},
33269
33270	/* Handle keystrokes. */
33271	_doKeyDown: function( event ) {
33272		var onSelect, dateStr, sel,
33273			inst = $.datepicker._getInst( event.target ),
33274			handled = true,
33275			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
33276
33277		inst._keyEvent = true;
33278		if ( $.datepicker._datepickerShowing ) {
33279			switch ( event.keyCode ) {
33280				case 9: $.datepicker._hideDatepicker();
33281						handled = false;
33282						break; // hide on tab out
33283				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
33284									$.datepicker._currentClass + ")", inst.dpDiv );
33285						if ( sel[ 0 ] ) {
33286							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
33287						}
33288
33289						onSelect = $.datepicker._get( inst, "onSelect" );
33290						if ( onSelect ) {
33291							dateStr = $.datepicker._formatDate( inst );
33292
33293							// Trigger custom callback
33294							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
33295						} else {
33296							$.datepicker._hideDatepicker();
33297						}
33298
33299						return false; // don't submit the form
33300				case 27: $.datepicker._hideDatepicker();
33301						break; // hide on escape
33302				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
33303							-$.datepicker._get( inst, "stepBigMonths" ) :
33304							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
33305						break; // previous month/year on page up/+ ctrl
33306				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
33307							+$.datepicker._get( inst, "stepBigMonths" ) :
33308							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
33309						break; // next month/year on page down/+ ctrl
33310				case 35: if ( event.ctrlKey || event.metaKey ) {
33311							$.datepicker._clearDate( event.target );
33312						}
33313						handled = event.ctrlKey || event.metaKey;
33314						break; // clear on ctrl or command +end
33315				case 36: if ( event.ctrlKey || event.metaKey ) {
33316							$.datepicker._gotoToday( event.target );
33317						}
33318						handled = event.ctrlKey || event.metaKey;
33319						break; // current on ctrl or command +home
33320				case 37: if ( event.ctrlKey || event.metaKey ) {
33321							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
33322						}
33323						handled = event.ctrlKey || event.metaKey;
33324
33325						// -1 day on ctrl or command +left
33326						if ( event.originalEvent.altKey ) {
33327							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
33328								-$.datepicker._get( inst, "stepBigMonths" ) :
33329								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
33330						}
33331
33332						// next month/year on alt +left on Mac
33333						break;
33334				case 38: if ( event.ctrlKey || event.metaKey ) {
33335							$.datepicker._adjustDate( event.target, -7, "D" );
33336						}
33337						handled = event.ctrlKey || event.metaKey;
33338						break; // -1 week on ctrl or command +up
33339				case 39: if ( event.ctrlKey || event.metaKey ) {
33340							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
33341						}
33342						handled = event.ctrlKey || event.metaKey;
33343
33344						// +1 day on ctrl or command +right
33345						if ( event.originalEvent.altKey ) {
33346							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
33347								+$.datepicker._get( inst, "stepBigMonths" ) :
33348								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
33349						}
33350
33351						// next month/year on alt +right
33352						break;
33353				case 40: if ( event.ctrlKey || event.metaKey ) {
33354							$.datepicker._adjustDate( event.target, +7, "D" );
33355						}
33356						handled = event.ctrlKey || event.metaKey;
33357						break; // +1 week on ctrl or command +down
33358				default: handled = false;
33359			}
33360		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
33361			$.datepicker._showDatepicker( this );
33362		} else {
33363			handled = false;
33364		}
33365
33366		if ( handled ) {
33367			event.preventDefault();
33368			event.stopPropagation();
33369		}
33370	},
33371
33372	/* Filter entered characters - based on date format. */
33373	_doKeyPress: function( event ) {
33374		var chars, chr,
33375			inst = $.datepicker._getInst( event.target );
33376
33377		if ( $.datepicker._get( inst, "constrainInput" ) ) {
33378			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
33379			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
33380			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
33381		}
33382	},
33383
33384	/* Synchronise manual entry and field/alternate field. */
33385	_doKeyUp: function( event ) {
33386		var date,
33387			inst = $.datepicker._getInst( event.target );
33388
33389		if ( inst.input.val() !== inst.lastVal ) {
33390			try {
33391				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
33392					( inst.input ? inst.input.val() : null ),
33393					$.datepicker._getFormatConfig( inst ) );
33394
33395				if ( date ) { // only if valid
33396					$.datepicker._setDateFromField( inst );
33397					$.datepicker._updateAlternate( inst );
33398					$.datepicker._updateDatepicker( inst );
33399				}
33400			} catch ( err ) {
33401			}
33402		}
33403		return true;
33404	},
33405
33406	/* Pop-up the date picker for a given input field.
33407	 * If false returned from beforeShow event handler do not show.
33408	 * @param  input  element - the input field attached to the date picker or
vendor: 4,332 bytes, lines 33409-33531
33409	 *					event - if triggered by focus
33410	 */
33411	_showDatepicker: function( input ) {
33412		input = input.target || input;
33413		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
33414			input = $( "input", input.parentNode )[ 0 ];
33415		}
33416
33417		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
33418			return;
33419		}
33420
33421		var inst, beforeShow, beforeShowSettings, isFixed,
33422			offset, showAnim, duration;
33423
33424		inst = $.datepicker._getInst( input );
33425		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
33426			$.datepicker._curInst.dpDiv.stop( true, true );
33427			if ( inst && $.datepicker._datepickerShowing ) {
33428				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
33429			}
33430		}
33431
33432		beforeShow = $.datepicker._get( inst, "beforeShow" );
33433		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
33434		if ( beforeShowSettings === false ) {
33435			return;
33436		}
33437		datepicker_extendRemove( inst.settings, beforeShowSettings );
33438
33439		inst.lastVal = null;
33440		$.datepicker._lastInput = input;
33441		$.datepicker._setDateFromField( inst );
33442
33443		if ( $.datepicker._inDialog ) { // hide cursor
33444			input.value = "";
33445		}
33446		if ( !$.datepicker._pos ) { // position below input
33447			$.datepicker._pos = $.datepicker._findPos( input );
33448			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
33449		}
33450
33451		isFixed = false;
33452		$( input ).parents().each( function() {
33453			isFixed |= $( this ).css( "position" ) === "fixed";
33454			return !isFixed;
33455		} );
33456
33457		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
33458		$.datepicker._pos = null;
33459
33460		//to avoid flashes on Firefox
33461		inst.dpDiv.empty();
33462
33463		// determine sizing offscreen
33464		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
33465		$.datepicker._updateDatepicker( inst );
33466
33467		// fix width for dynamic number of date pickers
33468		// and adjust position before showing
33469		offset = $.datepicker._checkOffset( inst, offset, isFixed );
33470		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
33471			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
33472			left: offset.left + "px", top: offset.top + "px" } );
33473
33474		if ( !inst.inline ) {
33475			showAnim = $.datepicker._get( inst, "showAnim" );
33476			duration = $.datepicker._get( inst, "duration" );
33477			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
33478			$.datepicker._datepickerShowing = true;
33479
33480			if ( $.effects && $.effects.effect[ showAnim ] ) {
33481				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
33482			} else {
33483				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
33484			}
33485
33486			if ( $.datepicker._shouldFocusInput( inst ) ) {
33487				inst.input.trigger( "focus" );
33488			}
33489
33490			$.datepicker._curInst = inst;
33491		}
33492	},
33493
33494	/* Generate the date picker content. */
33495	_updateDatepicker: function( inst ) {
33496		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
33497		datepicker_instActive = inst; // for delegate hover events
33498		inst.dpDiv.empty().append( this._generateHTML( inst ) );
33499		this._attachHandlers( inst );
33500
33501		var origyearshtml,
33502			numMonths = this._getNumberOfMonths( inst ),
33503			cols = numMonths[ 1 ],
33504			width = 17,
33505			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ),
33506			onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" );
33507
33508		if ( activeCell.length > 0 ) {
33509			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
33510		}
33511
33512		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
33513		if ( cols > 1 ) {
33514			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
33515		}
33516		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
33517			"Class" ]( "ui-datepicker-multi" );
33518		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
33519			"Class" ]( "ui-datepicker-rtl" );
33520
33521		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
33522			inst.input.trigger( "focus" );
33523		}
33524
33525		// Deffered render of the years select (to avoid flashes on Firefox)
33526		if ( inst.yearshtml ) {
33527			origyearshtml = inst.yearshtml;
33528			setTimeout( function() {
33529
33530				//assure that inst.yearshtml didn't change.
33531				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
vendor: 5,508 bytes, lines 33532-33690
33532					inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml );
33533				}
33534				origyearshtml = inst.yearshtml = null;
33535			}, 0 );
33536		}
33537
33538		if ( onUpdateDatepicker ) {
33539			onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] );
33540		}
33541	},
33542
33543	// #6694 - don't focus the input if it's already focused
33544	// this breaks the change event in IE
33545	// Support: IE and jQuery <1.9
33546	_shouldFocusInput: function( inst ) {
33547		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
33548	},
33549
33550	/* Check positioning to remain on screen. */
33551	_checkOffset: function( inst, offset, isFixed ) {
33552		var dpWidth = inst.dpDiv.outerWidth(),
33553			dpHeight = inst.dpDiv.outerHeight(),
33554			inputWidth = inst.input ? inst.input.outerWidth() : 0,
33555			inputHeight = inst.input ? inst.input.outerHeight() : 0,
33556			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
33557			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
33558
33559		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
33560		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
33561		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
33562
33563		// Now check if datepicker is showing outside window viewport - move to a better place if so.
33564		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
33565			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
33566		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
33567			Math.abs( dpHeight + inputHeight ) : 0 );
33568
33569		return offset;
33570	},
33571
33572	/* Find an object's position on the screen. */
33573	_findPos: function( obj ) {
33574		var position,
33575			inst = this._getInst( obj ),
33576			isRTL = this._get( inst, "isRTL" );
33577
33578		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) {
33579			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
33580		}
33581
33582		position = $( obj ).offset();
33583		return [ position.left, position.top ];
33584	},
33585
33586	/* Hide the date picker from view.
33587	 * @param  input  element - the input field attached to the date picker
33588	 */
33589	_hideDatepicker: function( input ) {
33590		var showAnim, duration, postProcess, onClose,
33591			inst = this._curInst;
33592
33593		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
33594			return;
33595		}
33596
33597		if ( this._datepickerShowing ) {
33598			showAnim = this._get( inst, "showAnim" );
33599			duration = this._get( inst, "duration" );
33600			postProcess = function() {
33601				$.datepicker._tidyDialog( inst );
33602			};
33603
33604			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
33605			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
33606				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
33607			} else {
33608				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
33609					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
33610			}
33611
33612			if ( !showAnim ) {
33613				postProcess();
33614			}
33615			this._datepickerShowing = false;
33616
33617			onClose = this._get( inst, "onClose" );
33618			if ( onClose ) {
33619				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
33620			}
33621
33622			this._lastInput = null;
33623			if ( this._inDialog ) {
33624				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
33625				if ( $.blockUI ) {
33626					$.unblockUI();
33627					$( "body" ).append( this.dpDiv );
33628				}
33629			}
33630			this._inDialog = false;
33631		}
33632	},
33633
33634	/* Tidy up after a dialog display. */
33635	_tidyDialog: function( inst ) {
33636		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
33637	},
33638
33639	/* Close date picker if clicked elsewhere. */
33640	_checkExternalClick: function( event ) {
33641		if ( !$.datepicker._curInst ) {
33642			return;
33643		}
33644
33645		var $target = $( event.target ),
33646			inst = $.datepicker._getInst( $target[ 0 ] );
33647
33648		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
33649				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
33650				!$target.hasClass( $.datepicker.markerClassName ) &&
33651				!$target.closest( "." + $.datepicker._triggerClass ).length &&
33652				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
33653			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
33654				$.datepicker._hideDatepicker();
33655		}
33656	},
33657
33658	/* Adjust one of the date sub-fields. */
33659	_adjustDate: function( id, offset, period ) {
33660		var target = $( id ),
33661			inst = this._getInst( target[ 0 ] );
33662
33663		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
33664			return;
33665		}
33666		this._adjustInstDate( inst, offset, period );
33667		this._updateDatepicker( inst );
33668	},
33669
33670	/* Action for current link. */
33671	_gotoToday: function( id ) {
33672		var date,
33673			target = $( id ),
33674			inst = this._getInst( target[ 0 ] );
33675
33676		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
33677			inst.selectedDay = inst.currentDay;
33678			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
33679			inst.drawYear = inst.selectedYear = inst.currentYear;
33680		} else {
33681			date = new Date();
33682			inst.selectedDay = date.getDate();
33683			inst.drawMonth = inst.selectedMonth = date.getMonth();
33684			inst.drawYear = inst.selectedYear = date.getFullYear();
33685		}
33686		this._notifyChange( inst );
33687		this._adjustDate( target );
33688	},
33689
33690	/* Action for selecting a new month/year. */
vendor: 4,615 bytes, lines 33691-33822
33691	_selectMonthYear: function( id, select, period ) {
33692		var target = $( id ),
33693			inst = this._getInst( target[ 0 ] );
33694
33695		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
33696		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
33697			parseInt( select.options[ select.selectedIndex ].value, 10 );
33698
33699		this._notifyChange( inst );
33700		this._adjustDate( target );
33701	},
33702
33703	/* Action for selecting a day. */
33704	_selectDay: function( id, month, year, td ) {
33705		var inst,
33706			target = $( id );
33707
33708		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
33709			return;
33710		}
33711
33712		inst = this._getInst( target[ 0 ] );
33713		inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) );
33714		inst.selectedMonth = inst.currentMonth = month;
33715		inst.selectedYear = inst.currentYear = year;
33716		this._selectDate( id, this._formatDate( inst,
33717			inst.currentDay, inst.currentMonth, inst.currentYear ) );
33718	},
33719
33720	/* Erase the input field and hide the date picker. */
33721	_clearDate: function( id ) {
33722		var target = $( id );
33723		this._selectDate( target, "" );
33724	},
33725
33726	/* Update the input field with the selected date. */
33727	_selectDate: function( id, dateStr ) {
33728		var onSelect,
33729			target = $( id ),
33730			inst = this._getInst( target[ 0 ] );
33731
33732		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
33733		if ( inst.input ) {
33734			inst.input.val( dateStr );
33735		}
33736		this._updateAlternate( inst );
33737
33738		onSelect = this._get( inst, "onSelect" );
33739		if ( onSelect ) {
33740			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
33741		} else if ( inst.input ) {
33742			inst.input.trigger( "change" ); // fire the change event
33743		}
33744
33745		if ( inst.inline ) {
33746			this._updateDatepicker( inst );
33747		} else {
33748			this._hideDatepicker();
33749			this._lastInput = inst.input[ 0 ];
33750			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
33751				inst.input.trigger( "focus" ); // restore focus
33752			}
33753			this._lastInput = null;
33754		}
33755	},
33756
33757	/* Update any alternate field to synchronise with the main field. */
33758	_updateAlternate: function( inst ) {
33759		var altFormat, date, dateStr,
33760			altField = this._get( inst, "altField" );
33761
33762		if ( altField ) { // update alternate field too
33763			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
33764			date = this._getDate( inst );
33765			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
33766			$( document ).find( altField ).val( dateStr );
33767		}
33768	},
33769
33770	/* Set as beforeShowDay function to prevent selection of weekends.
33771	 * @param  date  Date - the date to customise
33772	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
33773	 */
33774	noWeekends: function( date ) {
33775		var day = date.getDay();
33776		return [ ( day > 0 && day < 6 ), "" ];
33777	},
33778
33779	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
33780	 * @param  date  Date - the date to get the week for
33781	 * @return  number - the number of the week within the year that contains this date
33782	 */
33783	iso8601Week: function( date ) {
33784		var time,
33785			checkDate = new Date( date.getTime() );
33786
33787		// Find Thursday of this week starting on Monday
33788		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
33789
33790		time = checkDate.getTime();
33791		checkDate.setMonth( 0 ); // Compare with Jan 1
33792		checkDate.setDate( 1 );
33793		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
33794	},
33795
33796	/* Parse a string value into a date object.
33797	 * See formatDate below for the possible formats.
33798	 *
33799	 * @param  format string - the expected format of the date
33800	 * @param  value string - the date in the above format
33801	 * @param  settings Object - attributes include:
33802	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
33803	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
33804	 *					dayNames		string[7] - names of the days from Sunday (optional)
33805	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
33806	 *					monthNames		string[12] - names of the months (optional)
33807	 * @return  Date - the extracted date value or null if value is blank
33808	 */
33809	parseDate: function( format, value, settings ) {
33810		if ( format == null || value == null ) {
33811			throw "Invalid arguments";
33812		}
33813
33814		value = ( typeof value === "object" ? value.toString() : value + "" );
33815		if ( value === "" ) {
33816			return null;
33817		}
33818
33819		var iFormat, dim, extra,
33820			iValue = 0,
33821			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
33822			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp 
vendor: 5,431 bytes, lines 33822-34012
33822:
33823				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
33824			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
33825			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
33826			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
33827			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
33828			year = -1,
33829			month = -1,
33830			day = -1,
33831			doy = -1,
33832			literal = false,
33833			date,
33834
33835			// Check whether a format character is doubled
33836			lookAhead = function( match ) {
33837				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
33838				if ( matches ) {
33839					iFormat++;
33840				}
33841				return matches;
33842			},
33843
33844			// Extract a number from the string value
33845			getNumber = function( match ) {
33846				var isDoubled = lookAhead( match ),
33847					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
33848					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
33849					minSize = ( match === "y" ? size : 1 ),
33850					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
33851					num = value.substring( iValue ).match( digits );
33852				if ( !num ) {
33853					throw "Missing number at position " + iValue;
33854				}
33855				iValue += num[ 0 ].length;
33856				return parseInt( num[ 0 ], 10 );
33857			},
33858
33859			// Extract a name from the string value and convert to an index
33860			getName = function( match, shortNames, longNames ) {
33861				var index = -1,
33862					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
33863						return [ [ k, v ] ];
33864					} ).sort( function( a, b ) {
33865						return -( a[ 1 ].length - b[ 1 ].length );
33866					} );
33867
33868				$.each( names, function( i, pair ) {
33869					var name = pair[ 1 ];
33870					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
33871						index = pair[ 0 ];
33872						iValue += name.length;
33873						return false;
33874					}
33875				} );
33876				if ( index !== -1 ) {
33877					return index + 1;
33878				} else {
33879					throw "Unknown name at position " + iValue;
33880				}
33881			},
33882
33883			// Confirm that a literal character matches the string value
33884			checkLiteral = function() {
33885				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
33886					throw "Unexpected literal at position " + iValue;
33887				}
33888				iValue++;
33889			};
33890
33891		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
33892			if ( literal ) {
33893				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
33894					literal = false;
33895				} else {
33896					checkLiteral();
33897				}
33898			} else {
33899				switch ( format.charAt( iFormat ) ) {
33900					case "d":
33901						day = getNumber( "d" );
33902						break;
33903					case "D":
33904						getName( "D", dayNamesShort, dayNames );
33905						break;
33906					case "o":
33907						doy = getNumber( "o" );
33908						break;
33909					case "m":
33910						month = getNumber( "m" );
33911						break;
33912					case "M":
33913						month = getName( "M", monthNamesShort, monthNames );
33914						break;
33915					case "y":
33916						year = getNumber( "y" );
33917						break;
33918					case "@":
33919						date = new Date( getNumber( "@" ) );
33920						year = date.getFullYear();
33921						month = date.getMonth() + 1;
33922						day = date.getDate();
33923						break;
33924					case "!":
33925						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
33926						year = date.getFullYear();
33927						month = date.getMonth() + 1;
33928						day = date.getDate();
33929						break;
33930					case "'":
33931						if ( lookAhead( "'" ) ) {
33932							checkLiteral();
33933						} else {
33934							literal = true;
33935						}
33936						break;
33937					default:
33938						checkLiteral();
33939				}
33940			}
33941		}
33942
33943		if ( iValue < value.length ) {
33944			extra = value.substr( iValue );
33945			if ( !/^\s+/.test( extra ) ) {
33946				throw "Extra/unparsed characters found in date: " + extra;
33947			}
33948		}
33949
33950		if ( year === -1 ) {
33951			year = new Date().getFullYear();
33952		} else if ( year < 100 ) {
33953			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
33954				( year <= shortYearCutoff ? 0 : -100 );
33955		}
33956
33957		if ( doy > -1 ) {
33958			month = 1;
33959			day = doy;
33960			do {
33961				dim = this._getDaysInMonth( year, month - 1 );
33962				if ( day <= dim ) {
33963					break;
33964				}
33965				month++;
33966				day -= dim;
33967			} while ( true );
33968		}
33969
33970		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
33971		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
33972			throw "Invalid date"; // E.g. 31/02/00
33973		}
33974		return date;
33975	},
33976
33977	/* Standard date formats. */
33978	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
33979	COOKIE: "D, dd M yy",
33980	ISO_8601: "yy-mm-dd",
33981	RFC_822: "D, d M y",
33982	RFC_850: "DD, dd-M-y",
33983	RFC_1036: "D, d M y",
33984	RFC_1123: "D, d M yy",
33985	RFC_2822: "D, d M yy",
33986	RSS: "D, d M y", // RFC 822
33987	TICKS: "!",
33988	TIMESTAMP: "@",
33989	W3C: "yy-mm-dd", // ISO 8601
33990
33991	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
33992		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
33993
33994	/* Format a date object into a string value.
33995	 * The format can be combinations of the following:
33996	 * d  - day of month (no leading zero)
33997	 * dd - day of month (two digit)
33998	 * o  - day of year (no leading zeros)
33999	 * oo - day of year (three digit)
34000	 * D  - day name short
34001	 * DD - day name long
34002	 * m  - month of year (no leading zero)
34003	 * mm - month of year (two digit)
34004	 * M  - month name short
34005	 * MM - month name long
34006	 * y  - year (two digit)
34007	 * yy - year (four digit)
34008	 * @ - Unix timestamp (ms since 01/01/1970)
34009	 * ! - Windows ticks (100ns since 01/01/0001)
34010	 * "..." - literal text
34011	 * '' - single quote
34012	 *
vendor: 6,198 bytes, lines 34013-34212
34013	 * @param  format string - the desired format of the date
34014	 * @param  date Date - the date value to format
34015	 * @param  settings Object - attributes include:
34016	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
34017	 *					dayNames		string[7] - names of the days from Sunday (optional)
34018	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
34019	 *					monthNames		string[12] - names of the months (optional)
34020	 * @return  string - the date in the above format
34021	 */
34022	formatDate: function( format, date, settings ) {
34023		if ( !date ) {
34024			return "";
34025		}
34026
34027		var iFormat,
34028			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
34029			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
34030			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
34031			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
34032
34033			// Check whether a format character is doubled
34034			lookAhead = function( match ) {
34035				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
34036				if ( matches ) {
34037					iFormat++;
34038				}
34039				return matches;
34040			},
34041
34042			// Format a number, with leading zero if necessary
34043			formatNumber = function( match, value, len ) {
34044				var num = "" + value;
34045				if ( lookAhead( match ) ) {
34046					while ( num.length < len ) {
34047						num = "0" + num;
34048					}
34049				}
34050				return num;
34051			},
34052
34053			// Format a name, short or long as requested
34054			formatName = function( match, value, shortNames, longNames ) {
34055				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
34056			},
34057			output = "",
34058			literal = false;
34059
34060		if ( date ) {
34061			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
34062				if ( literal ) {
34063					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
34064						literal = false;
34065					} else {
34066						output += format.charAt( iFormat );
34067					}
34068				} else {
34069					switch ( format.charAt( iFormat ) ) {
34070						case "d":
34071							output += formatNumber( "d", date.getDate(), 2 );
34072							break;
34073						case "D":
34074							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
34075							break;
34076						case "o":
34077							output += formatNumber( "o",
34078								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
34079							break;
34080						case "m":
34081							output += formatNumber( "m", date.getMonth() + 1, 2 );
34082							break;
34083						case "M":
34084							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
34085							break;
34086						case "y":
34087							output += ( lookAhead( "y" ) ? date.getFullYear() :
34088								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
34089							break;
34090						case "@":
34091							output += date.getTime();
34092							break;
34093						case "!":
34094							output += date.getTime() * 10000 + this._ticksTo1970;
34095							break;
34096						case "'":
34097							if ( lookAhead( "'" ) ) {
34098								output += "'";
34099							} else {
34100								literal = true;
34101							}
34102							break;
34103						default:
34104							output += format.charAt( iFormat );
34105					}
34106				}
34107			}
34108		}
34109		return output;
34110	},
34111
34112	/* Extract all possible characters from the date format. */
34113	_possibleChars: function( format ) {
34114		var iFormat,
34115			chars = "",
34116			literal = false,
34117
34118			// Check whether a format character is doubled
34119			lookAhead = function( match ) {
34120				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
34121				if ( matches ) {
34122					iFormat++;
34123				}
34124				return matches;
34125			};
34126
34127		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
34128			if ( literal ) {
34129				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
34130					literal = false;
34131				} else {
34132					chars += format.charAt( iFormat );
34133				}
34134			} else {
34135				switch ( format.charAt( iFormat ) ) {
34136					case "d": case "m": case "y": case "@":
34137						chars += "0123456789";
34138						break;
34139					case "D": case "M":
34140						return null; // Accept anything
34141					case "'":
34142						if ( lookAhead( "'" ) ) {
34143							chars += "'";
34144						} else {
34145							literal = true;
34146						}
34147						break;
34148					default:
34149						chars += format.charAt( iFormat );
34150				}
34151			}
34152		}
34153		return chars;
34154	},
34155
34156	/* Get a setting value, defaulting if necessary. */
34157	_get: function( inst, name ) {
34158		return inst.settings[ name ] !== undefined ?
34159			inst.settings[ name ] : this._defaults[ name ];
34160	},
34161
34162	/* Parse existing date and initialise date picker. */
34163	_setDateFromField: function( inst, noDefault ) {
34164		if ( inst.input.val() === inst.lastVal ) {
34165			return;
34166		}
34167
34168		var dateFormat = this._get( inst, "dateFormat" ),
34169			dates = inst.lastVal = inst.input ? inst.input.val() : null,
34170			defaultDate = this._getDefaultDate( inst ),
34171			date = defaultDate,
34172			settings = this._getFormatConfig( inst );
34173
34174		try {
34175			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
34176		} catch ( event ) {
34177			dates = ( noDefault ? "" : dates );
34178		}
34179		inst.selectedDay = date.getDate();
34180		inst.drawMonth = inst.selectedMonth = date.getMonth();
34181		inst.drawYear = inst.selectedYear = date.getFullYear();
34182		inst.currentDay = ( dates ? date.getDate() : 0 );
34183		inst.currentMonth = ( dates ? date.getMonth() : 0 );
34184		inst.currentYear = ( dates ? date.getFullYear() : 0 );
34185		this._adjustInstDate( inst );
34186	},
34187
34188	/* Retrieve the default date shown on opening. */
34189	_getDefaultDate: function( inst ) {
34190		return this._restrictMinMax( inst,
34191			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
34192	},
34193
34194	/* A date may be specified as an exact value or a relative one. */
34195	_determineDate: function( inst, date, defaultDate ) {
34196		var offsetNumeric = function( offset ) {
34197				var date = new Date();
34198				date.setDate( date.getDate() + offset );
34199				return date;
34200			},
34201			offsetString = function( offset ) {
34202				try {
34203					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
34204						offset, $.datepicker._getFormatConfig( inst ) );
34205				} catch ( e ) {
34206
34207					// Ignore
34208				}
34209
34210				var date = ( offset.toLowerCase().match( /^c/ ) ?
34211					$.datepicker._getDate( inst ) : null ) || new Date(),
34212					year = date.getFullYear(),
vendor: 5,359 bytes, lines 34213-34351
34213					month = date.getMonth(),
34214					day = date.getDate(),
34215					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
34216					matches = pattern.exec( offset );
34217
34218				while ( matches ) {
34219					switch ( matches[ 2 ] || "d" ) {
34220						case "d" : case "D" :
34221							day += parseInt( matches[ 1 ], 10 ); break;
34222						case "w" : case "W" :
34223							day += parseInt( matches[ 1 ], 10 ) * 7; break;
34224						case "m" : case "M" :
34225							month += parseInt( matches[ 1 ], 10 );
34226							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
34227							break;
34228						case "y": case "Y" :
34229							year += parseInt( matches[ 1 ], 10 );
34230							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
34231							break;
34232					}
34233					matches = pattern.exec( offset );
34234				}
34235				return new Date( year, month, day );
34236			},
34237			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
34238				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
34239
34240		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
34241		if ( newDate ) {
34242			newDate.setHours( 0 );
34243			newDate.setMinutes( 0 );
34244			newDate.setSeconds( 0 );
34245			newDate.setMilliseconds( 0 );
34246		}
34247		return this._daylightSavingAdjust( newDate );
34248	},
34249
34250	/* Handle switch to/from daylight saving.
34251	 * Hours may be non-zero on daylight saving cut-over:
34252	 * > 12 when midnight changeover, but then cannot generate
34253	 * midnight datetime, so jump to 1AM, otherwise reset.
34254	 * @param  date  (Date) the date to check
34255	 * @return  (Date) the corrected date
34256	 */
34257	_daylightSavingAdjust: function( date ) {
34258		if ( !date ) {
34259			return null;
34260		}
34261		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
34262		return date;
34263	},
34264
34265	/* Set the date(s) directly. */
34266	_setDate: function( inst, date, noChange ) {
34267		var clear = !date,
34268			origMonth = inst.selectedMonth,
34269			origYear = inst.selectedYear,
34270			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
34271
34272		inst.selectedDay = inst.currentDay = newDate.getDate();
34273		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
34274		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
34275		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
34276			this._notifyChange( inst );
34277		}
34278		this._adjustInstDate( inst );
34279		if ( inst.input ) {
34280			inst.input.val( clear ? "" : this._formatDate( inst ) );
34281		}
34282	},
34283
34284	/* Retrieve the date(s) directly. */
34285	_getDate: function( inst ) {
34286		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
34287			this._daylightSavingAdjust( new Date(
34288			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
34289			return startDate;
34290	},
34291
34292	/* Attach the onxxx handlers.  These are declared statically so
34293	 * they work with static code transformers like Caja.
34294	 */
34295	_attachHandlers: function( inst ) {
34296		var stepMonths = this._get( inst, "stepMonths" ),
34297			id = "#" + inst.id.replace( /\\\\/g, "\\" );
34298		inst.dpDiv.find( "[data-handler]" ).map( function() {
34299			var handler = {
34300				prev: function() {
34301					$.datepicker._adjustDate( id, -stepMonths, "M" );
34302				},
34303				next: function() {
34304					$.datepicker._adjustDate( id, +stepMonths, "M" );
34305				},
34306				hide: function() {
34307					$.datepicker._hideDatepicker();
34308				},
34309				today: function() {
34310					$.datepicker._gotoToday( id );
34311				},
34312				selectDay: function() {
34313					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
34314					return false;
34315				},
34316				selectMonth: function() {
34317					$.datepicker._selectMonthYear( id, this, "M" );
34318					return false;
34319				},
34320				selectYear: function() {
34321					$.datepicker._selectMonthYear( id, this, "Y" );
34322					return false;
34323				}
34324			};
34325			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
34326		} );
34327	},
34328
34329	/* Generate the HTML for the current state of the date picker. */
34330	_generateHTML: function( inst ) {
34331		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
34332			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
34333			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
34334			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
34335			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
34336			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
34337			tempDate = new Date(),
34338			today = this._daylightSavingAdjust(
34339				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
34340			isRTL = this._get( inst, "isRTL" ),
34341			showButtonPanel = this._get( inst, "showButtonPanel" ),
34342			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
34343			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
34344			numMonths = this._getNumberOfMonths( inst ),
34345			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
34346			stepMonths = this._get( inst, "stepMonths" ),
34347			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
34348			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
34349				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
34350			minDate = this._getMinMaxDate( inst, "min" ),
34351			maxDate = this._getMinMaxDate( inst, "max" ),
vendor: 21,257 bytes, lines 34352-34866
34352			drawMonth = inst.drawMonth - showCurrentAtPos,
34353			drawYear = inst.drawYear;
34354
34355		if ( drawMonth < 0 ) {
34356			drawMonth += 12;
34357			drawYear--;
34358		}
34359		if ( maxDate ) {
34360			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
34361				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
34362			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
34363			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
34364				drawMonth--;
34365				if ( drawMonth < 0 ) {
34366					drawMonth = 11;
34367					drawYear--;
34368				}
34369			}
34370		}
34371		inst.drawMonth = drawMonth;
34372		inst.drawYear = drawYear;
34373
34374		prevText = this._get( inst, "prevText" );
34375		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
34376			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
34377			this._getFormatConfig( inst ) ) );
34378
34379		if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) {
34380			prev = $( "<a>" )
34381				.attr( {
34382					"class": "ui-datepicker-prev ui-corner-all",
34383					"data-handler": "prev",
34384					"data-event": "click",
34385					title: prevText
34386				} )
34387				.append(
34388					$( "<span>" )
34389						.addClass( "ui-icon ui-icon-circle-triangle-" +
34390							( isRTL ? "e" : "w" ) )
34391						.text( prevText )
34392				)[ 0 ].outerHTML;
34393		} else if ( hideIfNoPrevNext ) {
34394			prev = "";
34395		} else {
34396			prev = $( "<a>" )
34397				.attr( {
34398					"class": "ui-datepicker-prev ui-corner-all ui-state-disabled",
34399					title: prevText
34400				} )
34401				.append(
34402					$( "<span>" )
34403						.addClass( "ui-icon ui-icon-circle-triangle-" +
34404							( isRTL ? "e" : "w" ) )
34405						.text( prevText )
34406				)[ 0 ].outerHTML;
34407		}
34408
34409		nextText = this._get( inst, "nextText" );
34410		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
34411			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
34412			this._getFormatConfig( inst ) ) );
34413
34414		if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) {
34415			next = $( "<a>" )
34416				.attr( {
34417					"class": "ui-datepicker-next ui-corner-all",
34418					"data-handler": "next",
34419					"data-event": "click",
34420					title: nextText
34421				} )
34422				.append(
34423					$( "<span>" )
34424						.addClass( "ui-icon ui-icon-circle-triangle-" +
34425							( isRTL ? "w" : "e" ) )
34426						.text( nextText )
34427				)[ 0 ].outerHTML;
34428		} else if ( hideIfNoPrevNext ) {
34429			next = "";
34430		} else {
34431			next = $( "<a>" )
34432				.attr( {
34433					"class": "ui-datepicker-next ui-corner-all ui-state-disabled",
34434					title: nextText
34435				} )
34436				.append(
34437					$( "<span>" )
34438						.attr( "class", "ui-icon ui-icon-circle-triangle-" +
34439							( isRTL ? "w" : "e" ) )
34440						.text( nextText )
34441				)[ 0 ].outerHTML;
34442		}
34443
34444		currentText = this._get( inst, "currentText" );
34445		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
34446		currentText = ( !navigationAsDateFormat ? currentText :
34447			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
34448
34449		controls = "";
34450		if ( !inst.inline ) {
34451			controls = $( "<button>" )
34452				.attr( {
34453					type: "button",
34454					"class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all",
34455					"data-handler": "hide",
34456					"data-event": "click"
34457				} )
34458				.text( this._get( inst, "closeText" ) )[ 0 ].outerHTML;
34459		}
34460
34461		buttonPanel = "";
34462		if ( showButtonPanel ) {
34463			buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" )
34464				.append( isRTL ? controls : "" )
34465				.append( this._isInRange( inst, gotoDate ) ?
34466					$( "<button>" )
34467						.attr( {
34468							type: "button",
34469							"class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all",
34470							"data-handler": "today",
34471							"data-event": "click"
34472						} )
34473						.text( currentText ) :
34474					"" )
34475				.append( isRTL ? "" : controls )[ 0 ].outerHTML;
34476		}
34477
34478		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
34479		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
34480
34481		showWeek = this._get( inst, "showWeek" );
34482		dayNames = this._get( inst, "dayNames" );
34483		dayNamesMin = this._get( inst, "dayNamesMin" );
34484		monthNames = this._get( inst, "monthNames" );
34485		monthNamesShort = this._get( inst, "monthNamesShort" );
34486		beforeShowDay = this._get( inst, "beforeShowDay" );
34487		showOtherMonths = this._get( inst, "showOtherMonths" );
34488		selectOtherMonths = this._get( inst, "selectOtherMonths" );
34489		defaultDate = this._getDefaultDate( inst );
34490		html = "";
34491
34492		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
34493			group = "";
34494			this.maxRows = 4;
34495			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
34496				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
34497				cornerClass = " ui-corner-all";
34498				calender = "";
34499				if ( isMultiMonth ) {
34500					calender += "<div class='ui-datepicker-group";
34501					if ( numMonths[ 1 ] > 1 ) {
34502						switch ( col ) {
34503							case 0: calender += " ui-datepicker-group-first";
34504								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
34505							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
34506								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
34507							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
34508						}
34509					}
34510					calender += "'>";
34511				}
34512				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
34513					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
34514					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
34515					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
34516					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
34517					"</div><table class='ui-datepicker-calendar'><thead>" +
34518					"<tr>";
34519				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
34520				for ( dow = 0; dow < 7; dow++ ) { // days of the week
34521					day = ( dow + firstDay ) % 7;
34522					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
34523						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
34524				}
34525				calender += thead + "</tr></thead><tbody>";
34526				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
34527				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
34528					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
34529				}
34530				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
34531				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
34532				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
34533				this.maxRows = numRows;
34534				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
34535				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
34536					calender += "<tr>";
34537					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
34538						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
34539					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
34540						daySettings = ( beforeShowDay ?
34541							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
34542						otherMonth = ( printDate.getMonth() !== drawMonth );
34543						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
34544							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
34545						tbody += "<td class='" +
34546							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
34547							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
34548							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
34549							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
34550
34551							// or defaultDate is current printedDate and defaultDate is selectedDate
34552							" " + this._dayOverClass : "" ) + // highlight selected day
34553							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
34554							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
34555							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
34556							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
34557							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
34558							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
34559							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
34560							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
34561							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
34562							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
34563							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
34564							"' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader
34565							"' data-date='" + printDate.getDate() + // store date as data
34566							"'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
34567						printDate.setDate( printDate.getDate() + 1 );
34568						printDate = this._daylightSavingAdjust( printDate );
34569					}
34570					calender += tbody + "</tr>";
34571				}
34572				drawMonth++;
34573				if ( drawMonth > 11 ) {
34574					drawMonth = 0;
34575					drawYear++;
34576				}
34577				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
34578							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
34579				group += calender;
34580			}
34581			html += group;
34582		}
34583		html += buttonPanel;
34584		inst._keyEvent = false;
34585		return html;
34586	},
34587
34588	/* Generate the month and year header. */
34589	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
34590			secondary, monthNames, monthNamesShort ) {
34591
34592		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
34593			changeMonth = this._get( inst, "changeMonth" ),
34594			changeYear = this._get( inst, "changeYear" ),
34595			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
34596			selectMonthLabel = this._get( inst, "selectMonthLabel" ),
34597			selectYearLabel = this._get( inst, "selectYearLabel" ),
34598			html = "<div class='ui-datepicker-title'>",
34599			monthHtml = "";
34600
34601		// Month selection
34602		if ( secondary || !changeMonth ) {
34603			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
34604		} else {
34605			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
34606			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
34607			monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>";
34608			for ( month = 0; month < 12; month++ ) {
34609				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
34610					monthHtml += "<option value='" + month + "'" +
34611						( month === drawMonth ? " selected='selected'" : "" ) +
34612						">" + monthNamesShort[ month ] + "</option>";
34613				}
34614			}
34615			monthHtml += "</select>";
34616		}
34617
34618		if ( !showMonthAfterYear ) {
34619			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
34620		}
34621
34622		// Year selection
34623		if ( !inst.yearshtml ) {
34624			inst.yearshtml = "";
34625			if ( secondary || !changeYear ) {
34626				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
34627			} else {
34628
34629				// determine range of years to display
34630				years = this._get( inst, "yearRange" ).split( ":" );
34631				thisYear = new Date().getFullYear();
34632				determineYear = function( value ) {
34633					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
34634						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
34635						parseInt( value, 10 ) ) );
34636					return ( isNaN( year ) ? thisYear : year );
34637				};
34638				year = determineYear( years[ 0 ] );
34639				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
34640				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
34641				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
34642				inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>";
34643				for ( ; year <= endYear; year++ ) {
34644					inst.yearshtml += "<option value='" + year + "'" +
34645						( year === drawYear ? " selected='selected'" : "" ) +
34646						">" + year + "</option>";
34647				}
34648				inst.yearshtml += "</select>";
34649
34650				html += inst.yearshtml;
34651				inst.yearshtml = null;
34652			}
34653		}
34654
34655		html += this._get( inst, "yearSuffix" );
34656		if ( showMonthAfterYear ) {
34657			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
34658		}
34659		html += "</div>"; // Close datepicker_header
34660		return html;
34661	},
34662
34663	/* Adjust one of the date sub-fields. */
34664	_adjustInstDate: function( inst, offset, period ) {
34665		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
34666			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
34667			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
34668			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
34669
34670		inst.selectedDay = date.getDate();
34671		inst.drawMonth = inst.selectedMonth = date.getMonth();
34672		inst.drawYear = inst.selectedYear = date.getFullYear();
34673		if ( period === "M" || period === "Y" ) {
34674			this._notifyChange( inst );
34675		}
34676	},
34677
34678	/* Ensure a date is within any min/max bounds. */
34679	_restrictMinMax: function( inst, date ) {
34680		var minDate = this._getMinMaxDate( inst, "min" ),
34681			maxDate = this._getMinMaxDate( inst, "max" ),
34682			newDate = ( minDate && date < minDate ? minDate : date );
34683		return ( maxDate && newDate > maxDate ? maxDate : newDate );
34684	},
34685
34686	/* Notify change of month/year. */
34687	_notifyChange: function( inst ) {
34688		var onChange = this._get( inst, "onChangeMonthYear" );
34689		if ( onChange ) {
34690			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
34691				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
34692		}
34693	},
34694
34695	/* Determine the number of months to show. */
34696	_getNumberOfMonths: function( inst ) {
34697		var numMonths = this._get( inst, "numberOfMonths" );
34698		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
34699	},
34700
34701	/* Determine the current maximum date - ensure no time components are set. */
34702	_getMinMaxDate: function( inst, minMax ) {
34703		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
34704	},
34705
34706	/* Find the number of days in a given month. */
34707	_getDaysInMonth: function( year, month ) {
34708		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
34709	},
34710
34711	/* Find the day of the week of the first of a month. */
34712	_getFirstDayOfMonth: function( year, month ) {
34713		return new Date( year, month, 1 ).getDay();
34714	},
34715
34716	/* Determines if we should allow a "next/prev" month display change. */
34717	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
34718		var numMonths = this._getNumberOfMonths( inst ),
34719			date = this._daylightSavingAdjust( new Date( curYear,
34720			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
34721
34722		if ( offset < 0 ) {
34723			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
34724		}
34725		return this._isInRange( inst, date );
34726	},
34727
34728	/* Is the given date in the accepted range? */
34729	_isInRange: function( inst, date ) {
34730		var yearSplit, currentYear,
34731			minDate = this._getMinMaxDate( inst, "min" ),
34732			maxDate = this._getMinMaxDate( inst, "max" ),
34733			minYear = null,
34734			maxYear = null,
34735			years = this._get( inst, "yearRange" );
34736			if ( years ) {
34737				yearSplit = years.split( ":" );
34738				currentYear = new Date().getFullYear();
34739				minYear = parseInt( yearSplit[ 0 ], 10 );
34740				maxYear = parseInt( yearSplit[ 1 ], 10 );
34741				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
34742					minYear += currentYear;
34743				}
34744				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
34745					maxYear += currentYear;
34746				}
34747			}
34748
34749		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
34750			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
34751			( !minYear || date.getFullYear() >= minYear ) &&
34752			( !maxYear || date.getFullYear() <= maxYear ) );
34753	},
34754
34755	/* Provide the configuration settings for formatting/parsing. */
34756	_getFormatConfig: function( inst ) {
34757		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
34758		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
34759			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
34760		return { shortYearCutoff: shortYearCutoff,
34761			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
34762			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
34763	},
34764
34765	/* Format the given date for display. */
34766	_formatDate: function( inst, day, month, year ) {
34767		if ( !day ) {
34768			inst.currentDay = inst.selectedDay;
34769			inst.currentMonth = inst.selectedMonth;
34770			inst.currentYear = inst.selectedYear;
34771		}
34772		var date = ( day ? ( typeof day === "object" ? day :
34773			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
34774			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
34775		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
34776	}
34777} );
34778
34779/*
34780 * Bind hover events for datepicker elements.
34781 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
34782 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
34783 */
34784function datepicker_bindHover( dpDiv ) {
34785	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
34786	return dpDiv.on( "mouseout", selector, function() {
34787			$( this ).removeClass( "ui-state-hover" );
34788			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
34789				$( this ).removeClass( "ui-datepicker-prev-hover" );
34790			}
34791			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
34792				$( this ).removeClass( "ui-datepicker-next-hover" );
34793			}
34794		} )
34795		.on( "mouseover", selector, datepicker_handleMouseover );
34796}
34797
34798function datepicker_handleMouseover() {
34799	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
34800		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
34801		$( this ).addClass( "ui-state-hover" );
34802		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
34803			$( this ).addClass( "ui-datepicker-prev-hover" );
34804		}
34805		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
34806			$( this ).addClass( "ui-datepicker-next-hover" );
34807		}
34808	}
34809}
34810
34811/* jQuery extend now ignores nulls! */
34812function datepicker_extendRemove( target, props ) {
34813	$.extend( target, props );
34814	for ( var name in props ) {
34815		if ( props[ name ] == null ) {
34816			target[ name ] = props[ name ];
34817		}
34818	}
34819	return target;
34820}
34821
34822/* Invoke the datepicker functionality.
34823   @param  options  string - a command, optionally followed by additional parameters or
34824					Object - settings for attaching new datepicker functionality
34825   @return  jQuery object */
34826$.fn.datepicker = function( options ) {
34827
34828	/* Verify an empty collection wasn't passed - Fixes #6976 */
34829	if ( !this.length ) {
34830		return this;
34831	}
34832
34833	/* Initialise the date picker. */
34834	if ( !$.datepicker.initialized ) {
34835		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
34836		$.datepicker.initialized = true;
34837	}
34838
34839	/* Append datepicker main container to body if not exist. */
34840	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
34841		$( "body" ).append( $.datepicker.dpDiv );
34842	}
34843
34844	var otherArgs = Array.prototype.slice.call( arguments, 1 );
34845	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
34846		return $.datepicker[ "_" + options + "Datepicker" ].
34847			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
34848	}
34849	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
34850		return $.datepicker[ "_" + options + "Datepicker" ].
34851			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
34852	}
34853	return this.each( function() {
34854		if ( typeof options === "string" ) {
34855			$.datepicker[ "_" + options + "Datepicker" ]
34856				.apply( $.datepicker, [ this ].concat( otherArgs ) );
34857		} else {
34858			$.datepicker._attachDatepicker( this, options );
34859		}
34860	} );
34861};
34862
34863$.datepicker = new Datepicker(); // singleton instance
34864$.datepicker.initialized = false;
34865$.datepicker.uuid = new Date().getTime();
34866$.datepicker.version = "1.1
348663.0";
34867
34868return $.datepicker;
34869
34870} );
34871
34872
34873/***/ }),
34874/* 163 */
34875/***/ (function(module, exports, __webpack_require__) {
34876
34877var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
34878 * jQuery UI Keycode 1.13.0
34879 * http://jqueryui.com
34880 *
34881 * Copyright jQuery Foundation and other contributors
34882 * Released under the MIT license.
34883 * http://jquery.org/license
34884 */
34885
34886//>>label: Keycode
34887//>>group: Core
34888//>>description: Provide keycodes as keynames
34889//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
34890
34891( function( factory ) {
34892	"use strict";
34893
34894	if ( true ) {
34895
34896		// AMD. Register as an anonymous module.
34897		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2), __webpack_require__(5) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
34898				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
34899				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
34900				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
34901	} else {
34902
34903		// Browser globals
34904		factory( jQuery );
34905	}
34906} )( function( $ ) {
34907"use strict";
34908
34909return $.ui.keyCode = {
34910	BACKSPACE: 8,
34911	COMMA: 188,
34912	DELETE: 46,
34913	DOWN: 40,
34914	END: 35,
34915	ENTER: 13,
34916	ESCAPE: 27,
34917	HOME: 36,
34918	LEFT: 37,
34919	PAGE_DOWN: 34,
34920	PAGE_UP: 33,
34921	PERIOD: 190,
34922	RIGHT: 39,
34923	SPACE: 32,
34924	TAB: 9,
34925	UP: 38
34926};
34927
34928} );
34929
34930
34931/***/ }),
34932/* 164 */
34933/***/ (function(module, exports, __webpack_require__) {
34934
34935var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (factory) {
34936    if (true) {
34937        // AMD. Register as an anonymous module.
34938        !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(2)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
34939				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
34940				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
34941				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
34942    } else if (typeof exports === 'object') {
34943        // Node/CommonJS
34944        factory(require('jquery'));
34945    } else {
34946        // Browser globals
34947        factory(jQuery);
34948    }
34949}(function ($) {
34950
34951var ua = navigator.userAgent,
34952	iPhone = /iphone/i.test(ua),
34953	chrome = /chrome/i.test(ua),
34954	android = /android/i.test(ua),
34955	caretTimeoutId;
34956
34957$.mask = {
34958	//Predefined character definitions
34959	definitions: {
34960		'9': "[0-9]",
34961		'a': "[A-Za-z]",
34962		'*': "[A-Za-z0-9]"
34963	},
34964	autoclear: true,
34965	dataName: "rawMaskFn",
34966	placeholder: '_'
34967};
34968
34969$.fn.extend({
34970	//Helper Function for Caret positioning
34971	caret: function(begin, end) {
34972		var range;
34973
34974		if (this.length === 0 || this.is(":hidden") || this.get(0) !== document.activeElement) {
34975			return;
34976		}
34977
34978		if (typeof begin == 'number') {
34979			end = (typeof end === 'number') ? end : begin;
34980			return this.each(function() {
34981				if (this.setSelectionRange) {
34982					this.setSelectionRange(begin, end);
34983				} else if (this.createTextRange) {
34984					range = this.createTextRange();
34985					range.collapse(true);
34986					range.moveEnd('character', end);
34987					range.moveStart('character', begin);
34988					range.select();
34989				}
34990			});
34991		} else {
34992			if (this[0].setSelectionRange) {
34993				begin = this[0].selectionStart;
34994				end = this[0].selectionEnd;
34995			} else if (document.selection && document.selection.createRange) {
34996				range = document.selection.createRange();
34997				begin = 0 - range.duplicate().moveStart('character', -100000);
34998				end = begin + range.text.length;
34999			}
35000			return { begin: begin, end: end };
35001		}
35002	},
35003	unmask: function() {
35004		return this.trigger("unmask");
35005	},
35006	mask: function(mask, settings) {
35007		var input,
35008			defs,
35009			tests,
35010			partialPosition,
35011			firstNonMaskPos,
35012            lastRequiredNonMaskPos,
35013            len,
35014            oldVal;
35015
35016		if (!mask && this.length > 0) {
35017			input = $(this[0]);
35018            var fn = input.data($.mask.dataName)
35019			return fn?fn():undefined;
35020		}
35021
35022		settings = $.extend({
35023			autoclear: $.mask.autoclear,
35024			placeholder: $.mask.placeholder, // Load default placeholder
35025			completed: null
35026		}, settings);
35027
35028
35029		defs = $.mask.definitions;
35030		tests = [];
35031		partialPosition = len = mask.length;
35032		firstNonMaskPos = null;
35033
35034		mask = String(mask);
35035
35036		$.each(mask.split(""), function(i, c) {
35037			if (c == '?') {
35038				len--;
35039				partialPosition = i;
35040			} else if (defs[c]) {
35041				tests.push(new RegExp(defs[c]));
35042				if (firstNonMaskPos === null) {
35043					firstNonMaskPos = tests.length - 1;
35044				}
35045                if(i < partialPosition){
35046                    lastRequiredNonMaskPos = tests.length - 1;
35047                }
35048			} else {
35049				tests.push(null);
35050			}
35051		});
35052
35053		return this.trigger("unmask").each(function() {
35054			var input = $(this),
35055				buffer = $.map(
35056    				mask.split(""),
35057    				function(c, i) {
35058    					if (c != '?') {
35059    						return defs[c] ? getPlaceholder(i) : c;
35060    					}
35061    				}),
35062				defaultBuffer = buffer.join(''),
35063				focusText = input.val();
35064
35065            function tryFireCompleted(){
35066                if (!settings.completed) {
35067                    return;
35068                }
35069
35070                for (var i = firstNonMaskPos; i <= lastRequiredNonMaskPos; i++) {
35071                    if (tests[i] && buffer[i] === getPlaceholder(i)) {
35072                        return;
35073                    }
35074                }
35075                settings.completed.call(input);
35076            }
35077
35078            function getPlaceholder(i){
35079                if(i < settings.placeholder.length)
35080                    return settings.placeholder.charAt(i);
35081                return settings.placeholder.charAt(0);
35082            }
35083
35084			function seekNext(pos) {
35085				while (++pos < len && !tests[pos]);
35086				return pos;
35087			}
35088
35089			function seekPrev(pos) {
35090				while (--pos >= 0 && !tests[pos]);
35091				return pos;
35092			}
35093
35094			function shiftL(begin,end) {
35095				var i,
35096					j;
35097
35098				if (begin<0) {
35099					return;
35100				}
35101
35102				for (i = begin, j = seekNext(end); i < len; i++) {
35103					if (tests[i]) {
35104						if (j < len && tests[i].test(buffer[j])) {
35105							buffer[i] = buffer[j];
35106							buffer[j] = getPlaceholder(j);
35107						} else {
35108							break;
35109						}
35110
35111						j = seekNext(j);
35112					}
35113				}
35114				writeBuffer();
35115				input.caret(Math.max(firstNonMaskPos, begin));
35116			}
35117
35118			function shiftR(pos) {
35119				var i,
35120					c,
35121					j,
35122					t;
35123
35124				for (i = pos, c = getPlaceholder(pos); i < len; i++) {
35125					if (tests[i]) {
35126						j = seekNext(i);
35127						t = buffer[i];
35128						buffer[i] = c;
35129						if (j < len && tests[j].test(t)) {
35130							c = t;
35131						} else {
35132							break;
35133						}
35134					}
35135				}
35136			}
35137
35138			function androidInputEvent(e) {
35139				var curVal = input.val();
35140				var pos = input.caret();
35141				if (oldVal && oldVal.length && oldVal.length > curVal.length ) {
35142					// a deletion or backspace happened
35143					checkVal(true);
35144					while (pos.begin > 0 && !tests[pos.begin-1])
35145						pos.begin--;
35146					if (pos.begin === 0)
35147					{
35148						while (pos.begin < firstNonMaskPos && !tests[pos.begin])
35149							pos.begin++;
35150					}
35151					input.caret(pos.begin,pos.begin);
35152				} else {
35153					var pos2 = checkVal(true);
35154					var lastEnteredValue = curVal.charAt(pos.begin);
35155					if (pos.begin < len){
35156						if(!tests[pos.begin]){
35157							pos.begin++;
35158							if(tests[pos.begin].test(lastEnteredValue)){
35159								pos.begin++;
35160							}
35161						}else{
35162							if(tests[pos.begin].test(lastEnteredValue)){
35163								pos.begin++;
35164							}
35165						}
35166					}
35167					input.caret(pos.begin,pos.begin);
35168				}
35169				tryFireCompleted();
35170			}
35171
35172
35173			function blurEvent(e) {
35174                checkVal();
35175
35176                if (input.val() != focusText)
35177                    input.change();
35178            }
35179
35180			function keydownEvent(e) {
35181                if (input.prop("readonly")){
35182                    return;
35183                }
35184
35185				var k = e.which || e.keyCode,
35186					pos,
35187					begin,
35188					end;
35189                    oldVal = input.val();
35190				//backspace, delete, and escape get special treatment
35191				if (k === 8 || k === 46 || (iPhone && k === 127)) {
35192					pos = input.caret();
35193					begin = pos.begin;
35194					end = pos.end;
35195
35196					if (end - begin === 0) {
35197						begin=k!==46?seekPrev(begin):(end=seekNext(begin-1));
35198						end=k===46?seekNext(end):end;
35199					}
35200					clearBuffer(begin, end);
35201					shiftL(begin, end - 1);
35202
35203					e.preventDefault();
35204				} else if( k === 13 ) { // enter
35205					blurEvent.call(this, e);
35206				} else if (k === 27) { // escape
35207					input.val(focusText);
35208					input.caret(0, checkVal());
35209					e.preventDefault();
35210				}
35211			}
35212
35213			function keypressEvent(e) {
35214                if (input.prop("readonly")){
35215                    return;
35216                }
35217
35218				var k = e.which || e.keyCode,
35219					pos = input.caret(),
35220					p,
35221					c,
35222					next;
35223
35224				if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore
35225					return;
35226				} else if ( k && k !== 13 ) {
35227					if (pos.end - pos.begin !== 0){
35228						clearBuffer(pos.begin, pos.end);
35229						shiftL(pos.begin, pos.end-1);
35230					}
35231
35232					p = seekNext(pos.begin - 1);
35233					if (p < len) {
35234						c = String.fromCharCode(k);
35235						if (tests[p].test(c)) {
35236							shiftR(p);
35237
35238							buffer[p] = c;
35239							writeBuffer();
35240							next = seekNext(p);
35241
35242							if(android){
35243								//Path for CSP Violation on FireFox OS 1.1
35244								var proxy = function() {
35245									$.proxy($.fn.caret,input,next)();
35246								};
35247
35248								setTimeout(proxy,0);
35249							}else{
35250								input.caret(next);
35251							}
35252                            if(pos.begin <= lastRequiredNonMaskPos){
35253		                         tryFireCompleted();
35254                             }
35255						}
35256					}
35257					e.preventDefault();
35258				}
35259			}
35260
35261			function clearBuffer(start, end) {
35262				var i;
35263				for (i = start; i < end && i < len; i++) {
35264					if (tests[i]) {
35265						buffer[i] = getPlaceholder(i);
35266					}
35267				}
35268			}
35269
35270			function writeBuffer() { input.val(buffer.join('')); }
35271
35272			function checkVal(allow) {
35273				//try to place characters where they belong
35274				var test = input.val(),
35275					lastMatch = -1,
35276					i,
35277					c,
35278					pos;
35279
35280				for (i = 0, pos = 0; i < len; i++) {
35281					if (tests[i]) {
35282						buffer[i] = getPlaceholder(i);
35283						while (pos++ < test.length) {
35284							c = test.charAt(pos - 1);
35285							if (tests[i].test(c)) {
35286								buffer[i] = c;
35287								lastMatch = i;
35288								break;
35289							}
35290						}
35291						if (pos > test.length) {
35292							clearBuffer(i + 1, len);
35293							break;
35294						}
35295					} else {
35296                        if (buffer[i] === test.charAt(pos)) {
35297                            pos++;
35298                        }
35299                        if( i < partialPosition){
35300                            lastMatch = i;
35301                        }
35302					}
35303				}
35304				if (allow) {
35305					writeBuffer();
35306				} else if (lastMatch + 1 < partialPosition) {
35307					if (settings.autoclear || buffer.join('') === defaultBuffer) {
35308						// Invalid value. Remove it and replace it with the
35309						// mask, which is the default behavior.
35310						if(input.val()) input.val("");
35311						clearBuffer(0, len);
35312					} else {
35313						// Invalid value, but we opt to show the value to the
35314						// user and allow them to correct their mistake.
35315						writeBuffer();
35316					}
35317				} else {
35318					writeBuffer();
35319					input.val(input.val().substring(0, lastMatch + 1));
35320				}
35321				return (partialPosition ? i : firstNonMaskPos);
35322			}
35323
35324			input.data($.mask.dataName,function(){
35325				return $.map(buffer, function(c, i) {
35326					return tests[i]&&c!=getPlaceholder(i) ? c : null;
35327				}).join('');
35328			});
35329
35330
35331			input
35332				.one("unmask", function() {
35333					input
35334						.off(".mask")
35335						.removeData($.mask.dataName);
35336				})
35337				.on("focus.mask", function() {
35338                    if (input.prop("readonly")){
35339                        return;
35340                    }
35341
35342					clearTimeout(caretTimeoutId);
35343					var pos;
35344
35345					focusText = input.val();
35346
35347					pos = checkVal();
35348
35349					caretTimeoutId = setTimeout(function(){
35350                        if(input.get(0) !== document.activeElement){
35351                            return;
35352                        }
35353						writeBuffer();
35354						if (pos == mask.replace("?","").length) {
35355							input.caret(0, pos);
35356						} else {
35357							input.caret(pos);
35358						}
35359					}, 10);
35360				})
35361				.on("blur.mask", blurEvent)
35362				.on("keydown.mask", keydownEvent)
35363				.on("keypress.mask", keypressEvent)
35364				.on("input.mask paste.mask", function() {
35365                    if (input.prop("readonly")){
35366                        return;
35367                    }
35368
35369					setTimeout(function() {
35370						var pos=checkVal(true);
35371						input.caret(pos);
35372                        tryFireCompleted();
35373					}, 0);
35374				});
35375                if (chrome && android)
35376                {
35377                    input
35378                        .off('input.mask')
35379                        .on('input.mask', androidInputEvent);
35380                }
35381				checkVal(); //Perform initial check for existing values
35382		});
35383	}
35384});
35385}));
35386
35387
35388/***/ }),
35389/* 165 */
35390/***/ (function(module, exports, __webpack_require__) {
35391
35392/* WEBPACK VAR INJECTION */(function(jQuery) {// ==================================================
35393// fancyBox v3.5.7
35394//
35395// Licensed GPLv3 for open source use
35396// or fancyBox Commercial License for commercial use
35397//
35398// http://fancyapps.com/fancybox/
35399// Copyright 2019 fancyApps
35400//
35401// ==================================================
35402(function (window, document, $, undefined) {
35403  "use strict";
35404
35405  window.console = window.console || {
35406    info: function (stuff) {}
35407  };
35408
35409  // If there's no jQuery, fancyBox can't work
35410  // =========================================
35411
35412  if (!$) {
35413    return;
35414  }
35415
35416  // Check if fancyBox is already initialized
35417  // ========================================
35418
35419  if ($.fn.fancybox) {
35420    console.info("fancyBox already initialized");
35421
35422    return;
35423  }
35424
35425  // Private default settings
35426  // ========================
35427
35428  var defaults = {
35429    // Close existing modals
35430    // Set this to false if you do not need to stack multiple instances
35431    closeExisting: false,
35432
35433    // Enable infinite gallery navigation
35434    loop: false,
35435
35436    // Horizontal space between slides
35437    gutter: 50,
35438
35439    // Enable keyboard navigation
35440    keyboard: true,
35441
35442    // Should allow caption to overlap the content
35443    preventCaptionOverlap: true,
35444
35445    // Should display navigation arrows at the screen edges
35446    arrows: true,
35447
35448    // Should display counter at the top left corner
35449    infobar: true,
35450
35451    // Should display close button (using `btnTpl.smallBtn` template) over the content
35452    // Can be true, false, "auto"
35453    // If "auto" - will be automatically enabled for "html", "inline" or "ajax" items
35454    smallBtn: "auto",
35455
35456    // Should display toolbar (buttons at the top)
35457    // Can be true, false, "auto"
35458    // If "auto" - will be automatically hidden if "smallBtn" is enabled
35459    toolbar: "auto",
35460
35461    // What buttons should appear in the top right corner.
35462    // Buttons will be created using templates from `btnTpl` option
35463    // and they will be placed into toolbar (class="fancybox-toolbar"` element)
35464    buttons: [
35465      "zoom",
35466      //"share",
35467      "slideShow",
35468      //"fullScreen",
35469      //"download",
35470      "thumbs",
35471      "close"
35472    ],
35473
35474    // Detect "idle" time in seconds
35475    idleTime: 3,
35476
35477    // Disable right-click and use simple image protection for images
35478    protect: false,
35479
35480    // Shortcut to make content "modal" - disable keyboard navigtion, hide buttons, etc
35481    modal: false,
35482
35483    image: {
35484      // Wait for images to load before displaying
35485      //   true  - wait for image to load and then display;
35486      //   false - display thumbnail and load the full-sized image over top,
35487      //           requires predefined image dimensions (`data-width` and `data-height` attributes)
35488      preload: false
35489    },
35490
35491    ajax: {
35492      // Object containing settings for ajax request
35493      settings: {
35494        // This helps to indicate that request comes from the modal
35495        // Feel free to change naming
35496        data: {
35497          fancybox: true
35498        }
35499      }
35500    },
35501
35502    iframe: {
35503      // Iframe template
35504      tpl: '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" allowfullscreen="allowfullscreen" allow="autoplay; fullscreen" src=""></iframe>',
35505
35506      // Preload iframe before displaying it
35507      // This allows to calculate iframe content width and height
35508      // (note: Due to "Same Origin Policy", you can't get cross domain data).
35509      preload: true,
35510
35511      // Custom CSS styling for iframe wrapping element
35512      // You can use this to set custom iframe dimensions
35513      css: {},
35514
35515      // Iframe tag attributes
35516      attr: {
35517        scrolling: "auto"
35518      }
35519    },
35520
35521    // For HTML5 video only
35522    video: {
35523      tpl: '<video class="fancybox-video" controls controlsList="nodownload" poster="{{poster}}">' +
35524        '<source src="{{src}}" type="{{format}}" />' +
35525        'Sorry, your browser doesn\'t support embedded videos, <a href="{{src}}">download</a> and watch with your favorite video player!' +
35526        "</video>",
35527      format: "", // custom video format
35528      autoStart: true
35529    },
35530
35531    // Default content type if cannot be detected automatically
35532    defaultType: "image",
35533
35534    // Open/close animation type
35535    // Possible values:
35536    //   false            - disable
35537    //   "zoom"           - zoom images from/to thumbnail
35538    //   "fade"
35539    //   "zoom-in-out"
35540    //
35541    animationEffect: "zoom",
35542
35543    // Duration in ms for open/close animation
35544    animationDuration: 366,
35545
35546    // Should image change opacity while zooming
35547    // If opacity is "auto", then opacity will be changed if image and thumbnail have different aspect ratios
35548    zoomOpacity: "auto",
35549
35550    // Transition effect between slides
35551    //
35552    // Possible values:
35553    //   false            - disable
35554    //   "fade'
35555    //   "slide'
35556    //   "circular'
35557    //   "tube'
35558    //   "zoom-in-out'
35559    //   "rotate'
35560    //
35561    transitionEffect: "fade",
35562
35563    // Duration in ms for transition animation
35564    transitionDuration: 366,
35565
35566    // Custom CSS class for slide element
35567    slideClass: "",
35568
35569    // Custom CSS class for layout
35570    baseClass: "",
35571
35572    // Base template for layout
35573    baseTpl: '<div class="fancybox-container" role="dialog" tabindex="-1">' +
35574      '<div class="fancybox-bg"></div>' +
35575      '<div class="fancybox-inner">' +
35576      '<div class="fancybox-infobar"><span data-fancybox-index></span>&nbsp;/&nbsp;<span data-fancybox-count></span></div>' +
35577      '<div class="fancybox-toolbar">{{buttons}}</div>' +
35578      '<div class="fancybox-navigation">{{arrows}}</div>' +
35579      '<div class="fancybox-stage"></div>' +
35580      '<div class="fancybox-caption"><div class="fancybox-caption__body"></div></div>' +
35581      "</div>" +
35582      "</div>",
35583
35584    // Loading indicator template
35585    spinnerTpl: '<div class="fancybox-loading"></div>',
35586
35587    // Error message template
35588    errorTpl: '<div class="fancybox-error"><p>{{ERROR}}</p></div>',
35589
35590    btnTpl: {
35591      download: '<a download data-fancybox-download class="fancybox-button fancybox-button--download" title="{{DOWNLOAD}}" href="javascript:;">' +
35592        '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
vendor: 157,158 bytes, lines 35592-41066
35592<path d="M18.62 17.09V19H5.38v-1.91zm-2.97-6.96L17 11.45l-5 4.87-5-4.87 1.36-1.32 2.68 2.64V5h1.92v7.77z"/></svg>' +
35593        "</a>",
35594
35595      zoom: '<button data-fancybox-zoom class="fancybox-button fancybox-button--zoom" title="{{ZOOM}}">' +
35596        '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.7 17.3l-3-3a5.9 5.9 0 0 0-.6-7.6 5.9 5.9 0 0 0-8.4 0 5.9 5.9 0 0 0 0 8.4 5.9 5.9 0 0 0 7.7.7l3 3a1 1 0 0 0 1.3 0c.4-.5.4-1 0-1.5zM8.1 13.8a4 4 0 0 1 0-5.7 4 4 0 0 1 5.7 0 4 4 0 0 1 0 5.7 4 4 0 0 1-5.7 0z"/></svg>' +
35597        "</button>",
35598
35599      close: '<button data-fancybox-close class="fancybox-button fancybox-button--close" title="{{CLOSE}}">' +
35600        '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 10.6L6.6 5.2 5.2 6.6l5.4 5.4-5.4 5.4 1.4 1.4 5.4-5.4 5.4 5.4 1.4-1.4-5.4-5.4 5.4-5.4-1.4-1.4-5.4 5.4z"/></svg>' +
35601        "</button>",
35602
35603      // Arrows
35604      arrowLeft: '<button data-fancybox-prev class="fancybox-button fancybox-button--arrow_left" title="{{PREV}}">' +
35605        '<div><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.28 15.7l-1.34 1.37L5 12l4.94-5.07 1.34 1.38-2.68 2.72H19v1.94H8.6z"/></svg></div>' +
35606        "</button>",
35607
35608      arrowRight: '<button data-fancybox-next class="fancybox-button fancybox-button--arrow_right" title="{{NEXT}}">' +
35609        '<div><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.4 12.97l-2.68 2.72 1.34 1.38L19 12l-4.94-5.07-1.34 1.38 2.68 2.72H5v1.94z"/></svg></div>' +
35610        "</button>",
35611
35612      // This small close button will be appended to your html/inline/ajax content by default,
35613      // if "smallBtn" option is not set to false
35614      smallBtn: '<button type="button" data-fancybox-close class="fancybox-button fancybox-close-small" title="{{CLOSE}}">' +
35615        '<svg xmlns="http://www.w3.org/2000/svg" version="1" viewBox="0 0 24 24"><path d="M13 12l5-5-1-1-5 5-5-5-1 1 5 5-5 5 1 1 5-5 5 5 1-1z"/></svg>' +
35616        "</button>"
35617    },
35618
35619    // Container is injected into this element
35620    parentEl: "body",
35621
35622    // Hide browser vertical scrollbars; use at your own risk
35623    hideScrollbar: true,
35624
35625    // Focus handling
35626    // ==============
35627
35628    // Try to focus on the first focusable element after opening
35629    autoFocus: true,
35630
35631    // Put focus back to active element after closing
35632    backFocus: true,
35633
35634    // Do not let user to focus on element outside modal content
35635    trapFocus: true,
35636
35637    // Module specific options
35638    // =======================
35639
35640    fullScreen: {
35641      autoStart: false
35642    },
35643
35644    // Set `touch: false` to disable panning/swiping
35645    touch: {
35646      vertical: true, // Allow to drag content vertically
35647      momentum: true // Continue movement after releasing mouse/touch when panning
35648    },
35649
35650    // Hash value when initializing manually,
35651    // set `false` to disable hash change
35652    hash: null,
35653
35654    // Customize or add new media types
35655    // Example:
35656    /*
35657      media : {
35658        youtube : {
35659          params : {
35660            autoplay : 0
35661          }
35662        }
35663      }
35664    */
35665    media: {},
35666
35667    slideShow: {
35668      autoStart: false,
35669      speed: 3000
35670    },
35671
35672    thumbs: {
35673      autoStart: false, // Display thumbnails on opening
35674      hideOnClose: true, // Hide thumbnail grid when closing animation starts
35675      parentEl: ".fancybox-container", // Container is injected into this element
35676      axis: "y" // Vertical (y) or horizontal (x) scrolling
35677    },
35678
35679    // Use mousewheel to navigate gallery
35680    // If 'auto' - enabled for images only
35681    wheel: "auto",
35682
35683    // Callbacks
35684    //==========
35685
35686    // See Documentation/API/Events for more information
35687    // Example:
35688    /*
35689      afterShow: function( instance, current ) {
35690        console.info( 'Clicked element:' );
35691        console.info( current.opts.$orig );
35692      }
35693    */
35694
35695    onInit: $.noop, // When instance has been initialized
35696
35697    beforeLoad: $.noop, // Before the content of a slide is being loaded
35698    afterLoad: $.noop, // When the content of a slide is done loading
35699
35700    beforeShow: $.noop, // Before open animation starts
35701    afterShow: $.noop, // When content is done loading and animating
35702
35703    beforeClose: $.noop, // Before the instance attempts to close. Return false to cancel the close.
35704    afterClose: $.noop, // After instance has been closed
35705
35706    onActivate: $.noop, // When instance is brought to front
35707    onDeactivate: $.noop, // When other instance has been activated
35708
35709    // Interaction
35710    // ===========
35711
35712    // Use options below to customize taken action when user clicks or double clicks on the fancyBox area,
35713    // each option can be string or method that returns value.
35714    //
35715    // Possible values:
35716    //   "close"           - close instance
35717    //   "next"            - move to next gallery item
35718    //   "nextOrClose"     - move to next gallery item or close if gallery has only one item
35719    //   "toggleControls"  - show/hide controls
35720    //   "zoom"            - zoom image (if loaded)
35721    //   false             - do nothing
35722
35723    // Clicked on the content
35724    clickContent: function (current, event) {
35725      return current.type === "image" ? "zoom" : false;
35726    },
35727
35728    // Clicked on the slide
35729    clickSlide: "close",
35730
35731    // Clicked on the background (backdrop) element;
35732    // if you have not changed the layout, then most likely you need to use `clickSlide` option
35733    clickOutside: "close",
35734
35735    // Same as previous two, but for double click
35736    dblclickContent: false,
35737    dblclickSlide: false,
35738    dblclickOutside: false,
35739
35740    // Custom options when mobile device is detected
35741    // =============================================
35742
35743    mobile: {
35744      preventCaptionOverlap: false,
35745      idleTime: false,
35746      clickContent: function (current, event) {
35747        return current.type === "image" ? "toggleControls" : false;
35748      },
35749      clickSlide: function (current, event) {
35750        return current.type === "image" ? "toggleControls" : "close";
35751      },
35752      dblclickContent: function (current, event) {
35753        return current.type === "image" ? "zoom" : false;
35754      },
35755      dblclickSlide: function (current, event) {
35756        return current.type === "image" ? "zoom" : false;
35757      }
35758    },
35759
35760    // Internationalization
35761    // ====================
35762
35763    lang: "en",
35764    i18n: {
35765      en: {
35766        CLOSE: "Close",
35767        NEXT: "Next",
35768        PREV: "Previous",
35769        ERROR: "The requested content cannot be loaded. <br/> Please try again later.",
35770        PLAY_START: "Start slideshow",
35771        PLAY_STOP: "Pause slideshow",
35772        FULL_SCREEN: "Full screen",
35773        THUMBS: "Thumbnails",
35774        DOWNLOAD: "Download",
35775        SHARE: "Share",
35776        ZOOM: "Zoom"
35777      },
35778      de: {
35779        CLOSE: "Schlie&szlig;en",
35780        NEXT: "Weiter",
35781        PREV: "Zur&uuml;ck",
35782        ERROR: "Die angeforderten Daten konnten nicht geladen werden. <br/> Bitte versuchen Sie es sp&auml;ter nochmal.",
35783        PLAY_START: "Diaschau starten",
35784        PLAY_STOP: "Diaschau beenden",
35785        FULL_SCREEN: "Vollbild",
35786        THUMBS: "Vorschaubilder",
35787        DOWNLOAD: "Herunterladen",
35788        SHARE: "Teilen",
35789        ZOOM: "Vergr&ouml;&szlig;ern"
35790      }
35791    }
35792  };
35793
35794  // Few useful variables and methods
35795  // ================================
35796
35797  var $W = $(window);
35798  var $D = $(document);
35799
35800  var called = 0;
35801
35802  // Check if an object is a jQuery object and not a native JavaScript object
35803  // ========================================================================
35804  var isQuery = function (obj) {
35805    return obj && obj.hasOwnProperty && obj instanceof $;
35806  };
35807
35808  // Handle multiple browsers for "requestAnimationFrame" and "cancelAnimationFrame"
35809  // ===============================================================================
35810  var requestAFrame = (function () {
35811    return (
35812      window.requestAnimationFrame ||
35813      window.webkitRequestAnimationFrame ||
35814      window.mozRequestAnimationFrame ||
35815      window.oRequestAnimationFrame ||
35816      // if all else fails, use setTimeout
35817      function (callback) {
35818        return window.setTimeout(callback, 1000 / 60);
35819      }
35820    );
35821  })();
35822
35823  var cancelAFrame = (function () {
35824    return (
35825      window.cancelAnimationFrame ||
35826      window.webkitCancelAnimationFrame ||
35827      window.mozCancelAnimationFrame ||
35828      window.oCancelAnimationFrame ||
35829      function (id) {
35830        window.clearTimeout(id);
35831      }
35832    );
35833  })();
35834
35835  // Detect the supported transition-end event property name
35836  // =======================================================
35837  var transitionEnd = (function () {
35838    var el = document.createElement("fakeelement"),
35839      t;
35840
35841    var transitions = {
35842      transition: "transitionend",
35843      OTransition: "oTransitionEnd",
35844      MozTransition: "transitionend",
35845      WebkitTransition: "webkitTransitionEnd"
35846    };
35847
35848    for (t in transitions) {
35849      if (el.style[t] !== undefined) {
35850        return transitions[t];
35851      }
35852    }
35853
35854    return "transitionend";
35855  })();
35856
35857  // Force redraw on an element.
35858  // This helps in cases where the browser doesn't redraw an updated element properly
35859  // ================================================================================
35860  var forceRedraw = function ($el) {
35861    return $el && $el.length && $el[0].offsetHeight;
35862  };
35863
35864  // Exclude array (`buttons`) options from deep merging
35865  // ===================================================
35866  var mergeOpts = function (opts1, opts2) {
35867    var rez = $.extend(true, {}, opts1, opts2);
35868
35869    $.each(opts2, function (key, value) {
35870      if ($.isArray(value)) {
35871        rez[key] = value;
35872      }
35873    });
35874
35875    return rez;
35876  };
35877
35878  // How much of an element is visible in viewport
35879  // =============================================
35880
35881  var inViewport = function (elem) {
35882    var elemCenter, rez;
35883
35884    if (!elem || elem.ownerDocument !== document) {
35885      return false;
35886    }
35887
35888    $(".fancybox-container").css("pointer-events", "none");
35889
35890    elemCenter = {
35891      x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
35892      y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
35893    };
35894
35895    rez = document.elementFromPoint(elemCenter.x, elemCenter.y) === elem;
35896
35897    $(".fancybox-container").css("pointer-events", "");
35898
35899    return rez;
35900  };
35901
35902  // Class definition
35903  // ================
35904
35905  var FancyBox = function (content, opts, index) {
35906    var self = this;
35907
35908    self.opts = mergeOpts({
35909      index: index
35910    }, $.fancybox.defaults);
35911
35912    if ($.isPlainObject(opts)) {
35913      self.opts = mergeOpts(self.opts, opts);
35914    }
35915
35916    if ($.fancybox.isMobile) {
35917      self.opts = mergeOpts(self.opts, self.opts.mobile);
35918    }
35919
35920    self.id = self.opts.id || ++called;
35921
35922    self.currIndex = parseInt(self.opts.index, 10) || 0;
35923    self.prevIndex = null;
35924
35925    self.prevPos = null;
35926    self.currPos = 0;
35927
35928    self.firstRun = true;
35929
35930    // All group items
35931    self.group = [];
35932
35933    // Existing slides (for current, next and previous gallery items)
35934    self.slides = {};
35935
35936    // Create group elements
35937    self.addContent(content);
35938
35939    if (!self.group.length) {
35940      return;
35941    }
35942
35943    self.init();
35944  };
35945
35946  $.extend(FancyBox.prototype, {
35947    // Create DOM structure
35948    // ====================
35949
35950    init: function () {
35951      var self = this,
35952        firstItem = self.group[self.currIndex],
35953        firstItemOpts = firstItem.opts,
35954        $container,
35955        buttonStr;
35956
35957      if (firstItemOpts.closeExisting) {
35958        $.fancybox.close(true);
35959      }
35960
35961      // Hide scrollbars
35962      // ===============
35963
35964      $("body").addClass("fancybox-active");
35965
35966      if (
35967        !$.fancybox.getInstance() &&
35968        firstItemOpts.hideScrollbar !== false &&
35969        !$.fancybox.isMobile &&
35970        document.body.scrollHeight > window.innerHeight
35971      ) {
35972        $("head").append(
35973          '<style id="fancybox-style-noscroll" type="text/css">.compensate-for-scrollbar{margin-right:' +
35974          (window.innerWidth - document.documentElement.clientWidth) +
35975          "px;}</style>"
35976        );
35977
35978        $("body").addClass("compensate-for-scrollbar");
35979      }
35980
35981      // Build html markup and set references
35982      // ====================================
35983
35984      // Build html code for buttons and insert into main template
35985      buttonStr = "";
35986
35987      $.each(firstItemOpts.buttons, function (index, value) {
35988        buttonStr += firstItemOpts.btnTpl[value] || "";
35989      });
35990
35991      // Create markup from base template, it will be initially hidden to
35992      // avoid unnecessary work like painting while initializing is not complete
35993      $container = $(
35994          self.translate(
35995            self,
35996            firstItemOpts.baseTpl
35997            .replace("{{buttons}}", buttonStr)
35998            .replace("{{arrows}}", firstItemOpts.btnTpl.arrowLeft + firstItemOpts.btnTpl.arrowRight)
35999          )
36000        )
36001        .attr("id", "fancybox-container-" + self.id)
36002        .addClass(firstItemOpts.baseClass)
36003        .data("FancyBox", self)
36004        .appendTo(firstItemOpts.parentEl);
36005
36006      // Create object holding references to jQuery wrapped nodes
36007      self.$refs = {
36008        container: $container
36009      };
36010
36011      ["bg", "inner", "infobar", "toolbar", "stage", "caption", "navigation"].forEach(function (item) {
36012        self.$refs[item] = $container.find(".fancybox-" + item);
36013      });
36014
36015      self.trigger("onInit");
36016
36017      // Enable events, deactive previous instances
36018      self.activate();
36019
36020      // Build slides, load and reveal content
36021      self.jumpTo(self.currIndex);
36022    },
36023
36024    // Simple i18n support - replaces object keys found in template
36025    // with corresponding values
36026    // ============================================================
36027
36028    translate: function (obj, str) {
36029      var arr = obj.opts.i18n[obj.opts.lang] || obj.opts.i18n.en;
36030
36031      return str.replace(/\{\{(\w+)\}\}/g, function (match, n) {
36032        return arr[n] === undefined ? match : arr[n];
36033      });
36034    },
36035
36036    // Populate current group with fresh content
36037    // Check if each object has valid type and content
36038    // ===============================================
36039
36040    addContent: function (content) {
36041      var self = this,
36042        items = $.makeArray(content),
36043        thumbs;
36044
36045      $.each(items, function (i, item) {
36046        var obj = {},
36047          opts = {},
36048          $item,
36049          type,
36050          found,
36051          src,
36052          srcParts;
36053
36054        // Step 1 - Make sure we have an object
36055        // ====================================
36056
36057        if ($.isPlainObject(item)) {
36058          // We probably have manual usage here, something like
36059          // $.fancybox.open( [ { src : "image.jpg", type : "image" } ] )
36060
36061          obj = item;
36062          opts = item.opts || item;
36063        } else if ($.type(item) === "object" && $(item).length) {
36064          // Here we probably have jQuery collection returned by some selector
36065          $item = $(item);
36066
36067          // Support attributes like `data-options='{"touch" : false}'` and `data-touch='false'`
36068          opts = $item.data() || {};
36069          opts = $.extend(true, {}, opts, opts.options);
36070
36071          // Here we store clicked element
36072          opts.$orig = $item;
36073
36074          obj.src = self.opts.src || opts.src || $item.attr("href");
36075
36076          // Assume that simple syntax is used, for example:
36077          //   `$.fancybox.open( $("#test"), {} );`
36078          if (!obj.type && !obj.src) {
36079            obj.type = "inline";
36080            obj.src = item;
36081          }
36082        } else {
36083          // Assume we have a simple html code, for example:
36084          //   $.fancybox.open( '<div><h1>Hi!</h1></div>' );
36085          obj = {
36086            type: "html",
36087            src: item + ""
36088          };
36089        }
36090
36091        // Each gallery object has full collection of options
36092        obj.opts = $.extend(true, {}, self.opts, opts);
36093
36094        // Do not merge buttons array
36095        if ($.isArray(opts.buttons)) {
36096          obj.opts.buttons = opts.buttons;
36097        }
36098
36099        if ($.fancybox.isMobile && obj.opts.mobile) {
36100          obj.opts = mergeOpts(obj.opts, obj.opts.mobile);
36101        }
36102
36103        // Step 2 - Make sure we have content type, if not - try to guess
36104        // ==============================================================
36105
36106        type = obj.type || obj.opts.type;
36107        src = obj.src || "";
36108
36109        if (!type && src) {
36110          if ((found = src.match(/\.(mp4|mov|ogv|webm)((\?|#).*)?$/i))) {
36111            type = "video";
36112
36113            if (!obj.opts.video.format) {
36114              obj.opts.video.format = "video/" + (found[1] === "ogv" ? "ogg" : found[1]);
36115            }
36116          } else if (src.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i)) {
36117            type = "image";
36118          } else if (src.match(/\.(pdf)((\?|#).*)?$/i)) {
36119            type = "iframe";
36120            obj = $.extend(true, obj, {
36121              contentType: "pdf",
36122              opts: {
36123                iframe: {
36124                  preload: false
36125                }
36126              }
36127            });
36128          } else if (src.charAt(0) === "#") {
36129            type = "inline";
36130          }
36131        }
36132
36133        if (type) {
36134          obj.type = type;
36135        } else {
36136          self.trigger("objectNeedsType", obj);
36137        }
36138
36139        if (!obj.contentType) {
36140          obj.contentType = $.inArray(obj.type, ["html", "inline", "ajax"]) > -1 ? "html" : obj.type;
36141        }
36142
36143        // Step 3 - Some adjustments
36144        // =========================
36145
36146        obj.index = self.group.length;
36147
36148        if (obj.opts.smallBtn == "auto") {
36149          obj.opts.smallBtn = $.inArray(obj.type, ["html", "inline", "ajax"]) > -1;
36150        }
36151
36152        if (obj.opts.toolbar === "auto") {
36153          obj.opts.toolbar = !obj.opts.smallBtn;
36154        }
36155
36156        // Find thumbnail image, check if exists and if is in the viewport
36157        obj.$thumb = obj.opts.$thumb || null;
36158
36159        if (obj.opts.$trigger && obj.index === self.opts.index) {
36160          obj.$thumb = obj.opts.$trigger.find("img:first");
36161
36162          if (obj.$thumb.length) {
36163            obj.opts.$orig = obj.opts.$trigger;
36164          }
36165        }
36166
36167        if (!(obj.$thumb && obj.$thumb.length) && obj.opts.$orig) {
36168          obj.$thumb = obj.opts.$orig.find("img:first");
36169        }
36170
36171        if (obj.$thumb && !obj.$thumb.length) {
36172          obj.$thumb = null;
36173        }
36174
36175        obj.thumb = obj.opts.thumb || (obj.$thumb ? obj.$thumb[0].src : null);
36176
36177        // "caption" is a "special" option, it can be used to customize caption per gallery item
36178        if ($.type(obj.opts.caption) === "function") {
36179          obj.opts.caption = obj.opts.caption.apply(item, [self, obj]);
36180        }
36181
36182        if ($.type(self.opts.caption) === "function") {
36183          obj.opts.caption = self.opts.caption.apply(item, [self, obj]);
36184        }
36185
36186        // Make sure we have caption as a string or jQuery object
36187        if (!(obj.opts.caption instanceof $)) {
36188          obj.opts.caption = obj.opts.caption === undefined ? "" : obj.opts.caption + "";
36189        }
36190
36191        // Check if url contains "filter" used to filter the content
36192        // Example: "ajax.html #something"
36193        if (obj.type === "ajax") {
36194          srcParts = src.split(/\s+/, 2);
36195
36196          if (srcParts.length > 1) {
36197            obj.src = srcParts.shift();
36198
36199            obj.opts.filter = srcParts.shift();
36200          }
36201        }
36202
36203        // Hide all buttons and disable interactivity for modal items
36204        if (obj.opts.modal) {
36205          obj.opts = $.extend(true, obj.opts, {
36206            trapFocus: true,
36207            // Remove buttons
36208            infobar: 0,
36209            toolbar: 0,
36210
36211            smallBtn: 0,
36212
36213            // Disable keyboard navigation
36214            keyboard: 0,
36215
36216            // Disable some modules
36217            slideShow: 0,
36218            fullScreen: 0,
36219            thumbs: 0,
36220            touch: 0,
36221
36222            // Disable click event handlers
36223            clickContent: false,
36224            clickSlide: false,
36225            clickOutside: false,
36226            dblclickContent: false,
36227            dblclickSlide: false,
36228            dblclickOutside: false
36229          });
36230        }
36231
36232        // Step 4 - Add processed object to group
36233        // ======================================
36234
36235        self.group.push(obj);
36236      });
36237
36238      // Update controls if gallery is already opened
36239      if (Object.keys(self.slides).length) {
36240        self.updateControls();
36241
36242        // Update thumbnails, if needed
36243        thumbs = self.Thumbs;
36244
36245        if (thumbs && thumbs.isActive) {
36246          thumbs.create();
36247
36248          thumbs.focus();
36249        }
36250      }
36251    },
36252
36253    // Attach an event handler functions for:
36254    //   - navigation buttons
36255    //   - browser scrolling, resizing;
36256    //   - focusing
36257    //   - keyboard
36258    //   - detecting inactivity
36259    // ======================================
36260
36261    addEvents: function () {
36262      var self = this;
36263
36264      self.removeEvents();
36265
36266      // Make navigation elements clickable
36267      // ==================================
36268
36269      self.$refs.container
36270        .on("click.fb-close", "[data-fancybox-close]", function (e) {
36271          e.stopPropagation();
36272          e.preventDefault();
36273
36274          self.close(e);
36275        })
36276        .on("touchstart.fb-prev click.fb-prev", "[data-fancybox-prev]", function (e) {
36277          e.stopPropagation();
36278          e.preventDefault();
36279
36280          self.previous();
36281        })
36282        .on("touchstart.fb-next click.fb-next", "[data-fancybox-next]", function (e) {
36283          e.stopPropagation();
36284          e.preventDefault();
36285
36286          self.next();
36287        })
36288        .on("click.fb", "[data-fancybox-zoom]", function (e) {
36289          // Click handler for zoom button
36290          self[self.isScaledDown() ? "scaleToActual" : "scaleToFit"]();
36291        });
36292
36293      // Handle page scrolling and browser resizing
36294      // ==========================================
36295
36296      $W.on("orientationchange.fb resize.fb", function (e) {
36297        if (e && e.originalEvent && e.originalEvent.type === "resize") {
36298          if (self.requestId) {
36299            cancelAFrame(self.requestId);
36300          }
36301
36302          self.requestId = requestAFrame(function () {
36303            self.update(e);
36304          });
36305        } else {
36306          if (self.current && self.current.type === "iframe") {
36307            self.$refs.stage.hide();
36308          }
36309
36310          setTimeout(
36311            function () {
36312              self.$refs.stage.show();
36313
36314              self.update(e);
36315            },
36316            $.fancybox.isMobile ? 600 : 250
36317          );
36318        }
36319      });
36320
36321      $D.on("keydown.fb", function (e) {
36322        var instance = $.fancybox ? $.fancybox.getInstance() : null,
36323          current = instance.current,
36324          keycode = e.keyCode || e.which;
36325
36326        // Trap keyboard focus inside of the modal
36327        // =======================================
36328
36329        if (keycode == 9) {
36330          if (current.opts.trapFocus) {
36331            self.focus(e);
36332          }
36333
36334          return;
36335        }
36336
36337        // Enable keyboard navigation
36338        // ==========================
36339
36340        if (!current.opts.keyboard || e.ctrlKey || e.altKey || e.shiftKey || $(e.target).is("input,textarea,video,audio,select")) {
36341          return;
36342        }
36343
36344        // Backspace and Esc keys
36345        if (keycode === 8 || keycode === 27) {
36346          e.preventDefault();
36347
36348          self.close(e);
36349
36350          return;
36351        }
36352
36353        // Left arrow and Up arrow
36354        if (keycode === 37 || keycode === 38) {
36355          e.preventDefault();
36356
36357          self.previous();
36358
36359          return;
36360        }
36361
36362        // Righ arrow and Down arrow
36363        if (keycode === 39 || keycode === 40) {
36364          e.preventDefault();
36365
36366          self.next();
36367
36368          return;
36369        }
36370
36371        self.trigger("afterKeydown", e, keycode);
36372      });
36373
36374      // Hide controls after some inactivity period
36375      if (self.group[self.currIndex].opts.idleTime) {
36376        self.idleSecondsCounter = 0;
36377
36378        $D.on(
36379          "mousemove.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle",
36380          function (e) {
36381            self.idleSecondsCounter = 0;
36382
36383            if (self.isIdle) {
36384              self.showControls();
36385            }
36386
36387            self.isIdle = false;
36388          }
36389        );
36390
36391        self.idleInterval = window.setInterval(function () {
36392          self.idleSecondsCounter++;
36393
36394          if (self.idleSecondsCounter >= self.group[self.currIndex].opts.idleTime && !self.isDragging) {
36395            self.isIdle = true;
36396            self.idleSecondsCounter = 0;
36397
36398            self.hideControls();
36399          }
36400        }, 1000);
36401      }
36402    },
36403
36404    // Remove events added by the core
36405    // ===============================
36406
36407    removeEvents: function () {
36408      var self = this;
36409
36410      $W.off("orientationchange.fb resize.fb");
36411      $D.off("keydown.fb .fb-idle");
36412
36413      this.$refs.container.off(".fb-close .fb-prev .fb-next");
36414
36415      if (self.idleInterval) {
36416        window.clearInterval(self.idleInterval);
36417
36418        self.idleInterval = null;
36419      }
36420    },
36421
36422    // Change to previous gallery item
36423    // ===============================
36424
36425    previous: function (duration) {
36426      return this.jumpTo(this.currPos - 1, duration);
36427    },
36428
36429    // Change to next gallery item
36430    // ===========================
36431
36432    next: function (duration) {
36433      return this.jumpTo(this.currPos + 1, duration);
36434    },
36435
36436    // Switch to selected gallery item
36437    // ===============================
36438
36439    jumpTo: function (pos, duration) {
36440      var self = this,
36441        groupLen = self.group.length,
36442        firstRun,
36443        isMoved,
36444        loop,
36445        current,
36446        previous,
36447        slidePos,
36448        stagePos,
36449        prop,
36450        diff;
36451
36452      if (self.isDragging || self.isClosing || (self.isAnimating && self.firstRun)) {
36453        return;
36454      }
36455
36456      // Should loop?
36457      pos = parseInt(pos, 10);
36458      loop = self.current ? self.current.opts.loop : self.opts.loop;
36459
36460      if (!loop && (pos < 0 || pos >= groupLen)) {
36461        return false;
36462      }
36463
36464      // Check if opening for the first time; this helps to speed things up
36465      firstRun = self.firstRun = !Object.keys(self.slides).length;
36466
36467      // Create slides
36468      previous = self.current;
36469
36470      self.prevIndex = self.currIndex;
36471      self.prevPos = self.currPos;
36472
36473      current = self.createSlide(pos);
36474
36475      if (groupLen > 1) {
36476        if (loop || current.index < groupLen - 1) {
36477          self.createSlide(pos + 1);
36478        }
36479
36480        if (loop || current.index > 0) {
36481          self.createSlide(pos - 1);
36482        }
36483      }
36484
36485      self.current = current;
36486      self.currIndex = current.index;
36487      self.currPos = current.pos;
36488
36489      self.trigger("beforeShow", firstRun);
36490
36491      self.updateControls();
36492
36493      // Validate duration length
36494      current.forcedDuration = undefined;
36495
36496      if ($.isNumeric(duration)) {
36497        current.forcedDuration = duration;
36498      } else {
36499        duration = current.opts[firstRun ? "animationDuration" : "transitionDuration"];
36500      }
36501
36502      duration = parseInt(duration, 10);
36503
36504      // Check if user has swiped the slides or if still animating
36505      isMoved = self.isMoved(current);
36506
36507      // Make sure current slide is visible
36508      current.$slide.addClass("fancybox-slide--current");
36509
36510      // Fresh start - reveal container, current slide and start loading content
36511      if (firstRun) {
36512        if (current.opts.animationEffect && duration) {
36513          self.$refs.container.css("transition-duration", duration + "ms");
36514        }
36515
36516        self.$refs.container.addClass("fancybox-is-open").trigger("focus");
36517
36518        // Attempt to load content into slide
36519        // This will later call `afterLoad` -> `revealContent`
36520        self.loadSlide(current);
36521
36522        self.preload("image");
36523
36524        return;
36525      }
36526
36527      // Get actual slide/stage positions (before cleaning up)
36528      slidePos = $.fancybox.getTranslate(previous.$slide);
36529      stagePos = $.fancybox.getTranslate(self.$refs.stage);
36530
36531      // Clean up all slides
36532      $.each(self.slides, function (index, slide) {
36533        $.fancybox.stop(slide.$slide, true);
36534      });
36535
36536      if (previous.pos !== current.pos) {
36537        previous.isComplete = false;
36538      }
36539
36540      previous.$slide.removeClass("fancybox-slide--complete fancybox-slide--current");
36541
36542      // If slides are out of place, then animate them to correct position
36543      if (isMoved) {
36544        // Calculate horizontal swipe distance
36545        diff = slidePos.left - (previous.pos * slidePos.width + previous.pos * previous.opts.gutter);
36546
36547        $.each(self.slides, function (index, slide) {
36548          slide.$slide.removeClass("fancybox-animated").removeClass(function (index, className) {
36549            return (className.match(/(^|\s)fancybox-fx-\S+/g) || []).join(" ");
36550          });
36551
36552          // Make sure that each slide is in equal distance
36553          // This is mostly needed for freshly added slides, because they are not yet positioned
36554          var leftPos = slide.pos * slidePos.width + slide.pos * slide.opts.gutter;
36555
36556          $.fancybox.setTranslate(slide.$slide, {
36557            top: 0,
36558            left: leftPos - stagePos.left + diff
36559          });
36560
36561          if (slide.pos !== current.pos) {
36562            slide.$slide.addClass("fancybox-slide--" + (slide.pos > current.pos ? "next" : "previous"));
36563          }
36564
36565          // Redraw to make sure that transition will start
36566          forceRedraw(slide.$slide);
36567
36568          // Animate the slide
36569          $.fancybox.animate(
36570            slide.$slide, {
36571              top: 0,
36572              left: (slide.pos - current.pos) * slidePos.width + (slide.pos - current.pos) * slide.opts.gutter
36573            },
36574            duration,
36575            function () {
36576              slide.$slide
36577                .css({
36578                  transform: "",
36579                  opacity: ""
36580                })
36581                .removeClass("fancybox-slide--next fancybox-slide--previous");
36582
36583              if (slide.pos === self.currPos) {
36584                self.complete();
36585              }
36586            }
36587          );
36588        });
36589      } else if (duration && current.opts.transitionEffect) {
36590        // Set transition effect for previously active slide
36591        prop = "fancybox-animated fancybox-fx-" + current.opts.transitionEffect;
36592
36593        previous.$slide.addClass("fancybox-slide--" + (previous.pos > current.pos ? "next" : "previous"));
36594
36595        $.fancybox.animate(
36596          previous.$slide,
36597          prop,
36598          duration,
36599          function () {
36600            previous.$slide.removeClass(prop).removeClass("fancybox-slide--next fancybox-slide--previous");
36601          },
36602          false
36603        );
36604      }
36605
36606      if (current.isLoaded) {
36607        self.revealContent(current);
36608      } else {
36609        self.loadSlide(current);
36610      }
36611
36612      self.preload("image");
36613    },
36614
36615    // Create new "slide" element
36616    // These are gallery items  that are actually added to DOM
36617    // =======================================================
36618
36619    createSlide: function (pos) {
36620      var self = this,
36621        $slide,
36622        index;
36623
36624      index = pos % self.group.length;
36625      index = index < 0 ? self.group.length + index : index;
36626
36627      if (!self.slides[pos] && self.group[index]) {
36628        $slide = $('<div class="fancybox-slide"></div>').appendTo(self.$refs.stage);
36629
36630        self.slides[pos] = $.extend(true, {}, self.group[index], {
36631          pos: pos,
36632          $slide: $slide,
36633          isLoaded: false
36634        });
36635
36636        self.updateSlide(self.slides[pos]);
36637      }
36638
36639      return self.slides[pos];
36640    },
36641
36642    // Scale image to the actual size of the image;
36643    // x and y values should be relative to the slide
36644    // ==============================================
36645
36646    scaleToActual: function (x, y, duration) {
36647      var self = this,
36648        current = self.current,
36649        $content = current.$content,
36650        canvasWidth = $.fancybox.getTranslate(current.$slide).width,
36651        canvasHeight = $.fancybox.getTranslate(current.$slide).height,
36652        newImgWidth = current.width,
36653        newImgHeight = current.height,
36654        imgPos,
36655        posX,
36656        posY,
36657        scaleX,
36658        scaleY;
36659
36660      if (self.isAnimating || self.isMoved() || !$content || !(current.type == "image" && current.isLoaded && !current.hasError)) {
36661        return;
36662      }
36663
36664      self.isAnimating = true;
36665
36666      $.fancybox.stop($content);
36667
36668      x = x === undefined ? canvasWidth * 0.5 : x;
36669      y = y === undefined ? canvasHeight * 0.5 : y;
36670
36671      imgPos = $.fancybox.getTranslate($content);
36672
36673      imgPos.top -= $.fancybox.getTranslate(current.$slide).top;
36674      imgPos.left -= $.fancybox.getTranslate(current.$slide).left;
36675
36676      scaleX = newImgWidth / imgPos.width;
36677      scaleY = newImgHeight / imgPos.height;
36678
36679      // Get center position for original image
36680      posX = canvasWidth * 0.5 - newImgWidth * 0.5;
36681      posY = canvasHeight * 0.5 - newImgHeight * 0.5;
36682
36683      // Make sure image does not move away from edges
36684      if (newImgWidth > canvasWidth) {
36685        posX = imgPos.left * scaleX - (x * scaleX - x);
36686
36687        if (posX > 0) {
36688          posX = 0;
36689        }
36690
36691        if (posX < canvasWidth - newImgWidth) {
36692          posX = canvasWidth - newImgWidth;
36693        }
36694      }
36695
36696      if (newImgHeight > canvasHeight) {
36697        posY = imgPos.top * scaleY - (y * scaleY - y);
36698
36699        if (posY > 0) {
36700          posY = 0;
36701        }
36702
36703        if (posY < canvasHeight - newImgHeight) {
36704          posY = canvasHeight - newImgHeight;
36705        }
36706      }
36707
36708      self.updateCursor(newImgWidth, newImgHeight);
36709
36710      $.fancybox.animate(
36711        $content, {
36712          top: posY,
36713          left: posX,
36714          scaleX: scaleX,
36715          scaleY: scaleY
36716        },
36717        duration || 366,
36718        function () {
36719          self.isAnimating = false;
36720        }
36721      );
36722
36723      // Stop slideshow
36724      if (self.SlideShow && self.SlideShow.isActive) {
36725        self.SlideShow.stop();
36726      }
36727    },
36728
36729    // Scale image to fit inside parent element
36730    // ========================================
36731
36732    scaleToFit: function (duration) {
36733      var self = this,
36734        current = self.current,
36735        $content = current.$content,
36736        end;
36737
36738      if (self.isAnimating || self.isMoved() || !$content || !(current.type == "image" && current.isLoaded && !current.hasError)) {
36739        return;
36740      }
36741
36742      self.isAnimating = true;
36743
36744      $.fancybox.stop($content);
36745
36746      end = self.getFitPos(current);
36747
36748      self.updateCursor(end.width, end.height);
36749
36750      $.fancybox.animate(
36751        $content, {
36752          top: end.top,
36753          left: end.left,
36754          scaleX: end.width / $content.width(),
36755          scaleY: end.height / $content.height()
36756        },
36757        duration || 366,
36758        function () {
36759          self.isAnimating = false;
36760        }
36761      );
36762    },
36763
36764    // Calculate image size to fit inside viewport
36765    // ===========================================
36766
36767    getFitPos: function (slide) {
36768      var self = this,
36769        $content = slide.$content,
36770        $slide = slide.$slide,
36771        width = slide.width || slide.opts.width,
36772        height = slide.height || slide.opts.height,
36773        maxWidth,
36774        maxHeight,
36775        minRatio,
36776        aspectRatio,
36777        rez = {};
36778
36779      if (!slide.isLoaded || !$content || !$content.length) {
36780        return false;
36781      }
36782
36783      maxWidth = $.fancybox.getTranslate(self.$refs.stage).width;
36784      maxHeight = $.fancybox.getTranslate(self.$refs.stage).height;
36785
36786      maxWidth -=
36787        parseFloat($slide.css("paddingLeft")) +
36788        parseFloat($slide.css("paddingRight")) +
36789        parseFloat($content.css("marginLeft")) +
36790        parseFloat($content.css("marginRight"));
36791
36792      maxHeight -=
36793        parseFloat($slide.css("paddingTop")) +
36794        parseFloat($slide.css("paddingBottom")) +
36795        parseFloat($content.css("marginTop")) +
36796        parseFloat($content.css("marginBottom"));
36797
36798      if (!width || !height) {
36799        width = maxWidth;
36800        height = maxHeight;
36801      }
36802
36803      minRatio = Math.min(1, maxWidth / width, maxHeight / height);
36804
36805      width = minRatio * width;
36806      height = minRatio * height;
36807
36808      // Adjust width/height to precisely fit into container
36809      if (width > maxWidth - 0.5) {
36810        width = maxWidth;
36811      }
36812
36813      if (height > maxHeight - 0.5) {
36814        height = maxHeight;
36815      }
36816
36817      if (slide.type === "image") {
36818        rez.top = Math.floor((maxHeight - height) * 0.5) + parseFloat($slide.css("paddingTop"));
36819        rez.left = Math.floor((maxWidth - width) * 0.5) + parseFloat($slide.css("paddingLeft"));
36820      } else if (slide.contentType === "video") {
36821        // Force aspect ratio for the video
36822        // "I say the whole world must learn of our peaceful ways… by force!"
36823        aspectRatio = slide.opts.width && slide.opts.height ? width / height : slide.opts.ratio || 16 / 9;
36824
36825        if (height > width / aspectRatio) {
36826          height = width / aspectRatio;
36827        } else if (width > height * aspectRatio) {
36828          width = height * aspectRatio;
36829        }
36830      }
36831
36832      rez.width = width;
36833      rez.height = height;
36834
36835      return rez;
36836    },
36837
36838    // Update content size and position for all slides
36839    // ==============================================
36840
36841    update: function (e) {
36842      var self = this;
36843
36844      $.each(self.slides, function (key, slide) {
36845        self.updateSlide(slide, e);
36846      });
36847    },
36848
36849    // Update slide content position and size
36850    // ======================================
36851
36852    updateSlide: function (slide, e) {
36853      var self = this,
36854        $content = slide && slide.$content,
36855        width = slide.width || slide.opts.width,
36856        height = slide.height || slide.opts.height,
36857        $slide = slide.$slide;
36858
36859      // First, prevent caption overlap, if needed
36860      self.adjustCaption(slide);
36861
36862      // Then resize content to fit inside the slide
36863      if ($content && (width || height || slide.contentType === "video") && !slide.hasError) {
36864        $.fancybox.stop($content);
36865
36866        $.fancybox.setTranslate($content, self.getFitPos(slide));
36867
36868        if (slide.pos === self.currPos) {
36869          self.isAnimating = false;
36870
36871          self.updateCursor();
36872        }
36873      }
36874
36875      // Then some adjustments
36876      self.adjustLayout(slide);
36877
36878      if ($slide.length) {
36879        $slide.trigger("refresh");
36880
36881        if (slide.pos === self.currPos) {
36882          self.$refs.toolbar
36883            .add(self.$refs.navigation.find(".fancybox-button--arrow_right"))
36884            .toggleClass("compensate-for-scrollbar", $slide.get(0).scrollHeight > $slide.get(0).clientHeight);
36885        }
36886      }
36887
36888      self.trigger("onUpdate", slide, e);
36889    },
36890
36891    // Horizontally center slide
36892    // =========================
36893
36894    centerSlide: function (duration) {
36895      var self = this,
36896        current = self.current,
36897        $slide = current.$slide;
36898
36899      if (self.isClosing || !current) {
36900        return;
36901      }
36902
36903      $slide.siblings().css({
36904        transform: "",
36905        opacity: ""
36906      });
36907
36908      $slide
36909        .parent()
36910        .children()
36911        .removeClass("fancybox-slide--previous fancybox-slide--next");
36912
36913      $.fancybox.animate(
36914        $slide, {
36915          top: 0,
36916          left: 0,
36917          opacity: 1
36918        },
36919        duration === undefined ? 0 : duration,
36920        function () {
36921          // Clean up
36922          $slide.css({
36923            transform: "",
36924            opacity: ""
36925          });
36926
36927          if (!current.isComplete) {
36928            self.complete();
36929          }
36930        },
36931        false
36932      );
36933    },
36934
36935    // Check if current slide is moved (swiped)
36936    // ========================================
36937
36938    isMoved: function (slide) {
36939      var current = slide || this.current,
36940        slidePos,
36941        stagePos;
36942
36943      if (!current) {
36944        return false;
36945      }
36946
36947      stagePos = $.fancybox.getTranslate(this.$refs.stage);
36948      slidePos = $.fancybox.getTranslate(current.$slide);
36949
36950      return (
36951        !current.$slide.hasClass("fancybox-animated") &&
36952        (Math.abs(slidePos.top - stagePos.top) > 0.5 || Math.abs(slidePos.left - stagePos.left) > 0.5)
36953      );
36954    },
36955
36956    // Update cursor style depending if content can be zoomed
36957    // ======================================================
36958
36959    updateCursor: function (nextWidth, nextHeight) {
36960      var self = this,
36961        current = self.current,
36962        $container = self.$refs.container,
36963        canPan,
36964        isZoomable;
36965
36966      if (!current || self.isClosing || !self.Guestures) {
36967        return;
36968      }
36969
36970      $container.removeClass("fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-zoomOut fancybox-can-swipe fancybox-can-pan");
36971
36972      canPan = self.canPan(nextWidth, nextHeight);
36973
36974      isZoomable = canPan ? true : self.isZoomable();
36975
36976      $container.toggleClass("fancybox-is-zoomable", isZoomable);
36977
36978      $("[data-fancybox-zoom]").prop("disabled", !isZoomable);
36979
36980      if (canPan) {
36981        $container.addClass("fancybox-can-pan");
36982      } else if (
36983        isZoomable &&
36984        (current.opts.clickContent === "zoom" || ($.isFunction(current.opts.clickContent) && current.opts.clickContent(current) == "zoom"))
36985      ) {
36986        $container.addClass("fancybox-can-zoomIn");
36987      } else if (current.opts.touch && (current.opts.touch.vertical || self.group.length > 1) && current.contentType !== "video") {
36988        $container.addClass("fancybox-can-swipe");
36989      }
36990    },
36991
36992    // Check if current slide is zoomable
36993    // ==================================
36994
36995    isZoomable: function () {
36996      var self = this,
36997        current = self.current,
36998        fitPos;
36999
37000      // Assume that slide is zoomable if:
37001      //   - image is still loading
37002      //   - actual size of the image is smaller than available area
37003      if (current && !self.isClosing && current.type === "image" && !current.hasError) {
37004        if (!current.isLoaded) {
37005          return true;
37006        }
37007
37008        fitPos = self.getFitPos(current);
37009
37010        if (fitPos && (current.width > fitPos.width || current.height > fitPos.height)) {
37011          return true;
37012        }
37013      }
37014
37015      return false;
37016    },
37017
37018    // Check if current image dimensions are smaller than actual
37019    // =========================================================
37020
37021    isScaledDown: function (nextWidth, nextHeight) {
37022      var self = this,
37023        rez = false,
37024        current = self.current,
37025        $content = current.$content;
37026
37027      if (nextWidth !== undefined && nextHeight !== undefined) {
37028        rez = nextWidth < current.width && nextHeight < current.height;
37029      } else if ($content) {
37030        rez = $.fancybox.getTranslate($content);
37031        rez = rez.width < current.width && rez.height < current.height;
37032      }
37033
37034      return rez;
37035    },
37036
37037    // Check if image dimensions exceed parent element
37038    // ===============================================
37039
37040    canPan: function (nextWidth, nextHeight) {
37041      var self = this,
37042        current = self.current,
37043        pos = null,
37044        rez = false;
37045
37046      if (current.type === "image" && (current.isComplete || (nextWidth && nextHeight)) && !current.hasError) {
37047        rez = self.getFitPos(current);
37048
37049        if (nextWidth !== undefined && nextHeight !== undefined) {
37050          pos = {
37051            width: nextWidth,
37052            height: nextHeight
37053          };
37054        } else if (current.isComplete) {
37055          pos = $.fancybox.getTranslate(current.$content);
37056        }
37057
37058        if (pos && rez) {
37059          rez = Math.abs(pos.width - rez.width) > 1.5 || Math.abs(pos.height - rez.height) > 1.5;
37060        }
37061      }
37062
37063      return rez;
37064    },
37065
37066    // Load content into the slide
37067    // ===========================
37068
37069    loadSlide: function (slide) {
37070      var self = this,
37071        type,
37072        $slide,
37073        ajaxLoad;
37074
37075      if (slide.isLoading || slide.isLoaded) {
37076        return;
37077      }
37078
37079      slide.isLoading = true;
37080
37081      if (self.trigger("beforeLoad", slide) === false) {
37082        slide.isLoading = false;
37083
37084        return false;
37085      }
37086
37087      type = slide.type;
37088      $slide = slide.$slide;
37089
37090      $slide
37091        .off("refresh")
37092        .trigger("onReset")
37093        .addClass(slide.opts.slideClass);
37094
37095      // Create content depending on the type
37096      switch (type) {
37097        case "image":
37098          self.setImage(slide);
37099
37100          break;
37101
37102        case "iframe":
37103          self.setIframe(slide);
37104
37105          break;
37106
37107        case "html":
37108          self.setContent(slide, slide.src || slide.content);
37109
37110          break;
37111
37112        case "video":
37113          self.setContent(
37114            slide,
37115            slide.opts.video.tpl
37116            .replace(/\{\{src\}\}/gi, slide.src)
37117            .replace("{{format}}", slide.opts.videoFormat || slide.opts.video.format || "")
37118            .replace("{{poster}}", slide.thumb || "")
37119          );
37120
37121          break;
37122
37123        case "inline":
37124          if ($(slide.src).length) {
37125            self.setContent(slide, $(slide.src));
37126          } else {
37127            self.setError(slide);
37128          }
37129
37130          break;
37131
37132        case "ajax":
37133          self.showLoading(slide);
37134
37135          ajaxLoad = $.ajax(
37136            $.extend({}, slide.opts.ajax.settings, {
37137              url: slide.src,
37138              success: function (data, textStatus) {
37139                if (textStatus === "success") {
37140                  self.setContent(slide, data);
37141                }
37142              },
37143              error: function (jqXHR, textStatus) {
37144                if (jqXHR && textStatus !== "abort") {
37145                  self.setError(slide);
37146                }
37147              }
37148            })
37149          );
37150
37151          $slide.one("onReset", function () {
37152            ajaxLoad.abort();
37153          });
37154
37155          break;
37156
37157        default:
37158          self.setError(slide);
37159
37160          break;
37161      }
37162
37163      return true;
37164    },
37165
37166    // Use thumbnail image, if possible
37167    // ================================
37168
37169    setImage: function (slide) {
37170      var self = this,
37171        ghost;
37172
37173      // Check if need to show loading icon
37174      setTimeout(function () {
37175        var $img = slide.$image;
37176
37177        if (!self.isClosing && slide.isLoading && (!$img || !$img.length || !$img[0].complete) && !slide.hasError) {
37178          self.showLoading(slide);
37179        }
37180      }, 50);
37181
37182      //Check if image has srcset
37183      self.checkSrcset(slide);
37184
37185      // This will be wrapper containing both ghost and actual image
37186      slide.$content = $('<div class="fancybox-content"></div>')
37187        .addClass("fancybox-is-hidden")
37188        .appendTo(slide.$slide.addClass("fancybox-slide--image"));
37189
37190      // If we have a thumbnail, we can display it while actual image is loading
37191      // Users will not stare at black screen and actual image will appear gradually
37192      if (slide.opts.preload !== false && slide.opts.width && slide.opts.height && slide.thumb) {
37193        slide.width = slide.opts.width;
37194        slide.height = slide.opts.height;
37195
37196        ghost = document.createElement("img");
37197
37198        ghost.onerror = function () {
37199          $(this).remove();
37200
37201          slide.$ghost = null;
37202        };
37203
37204        ghost.onload = function () {
37205          self.afterLoad(slide);
37206        };
37207
37208        slide.$ghost = $(ghost)
37209          .addClass("fancybox-image")
37210          .appendTo(slide.$content)
37211          .attr("src", slide.thumb);
37212      }
37213
37214      // Start loading actual image
37215      self.setBigImage(slide);
37216    },
37217
37218    // Check if image has srcset and get the source
37219    // ============================================
37220    checkSrcset: function (slide) {
37221      var srcset = slide.opts.srcset || slide.opts.image.srcset,
37222        found,
37223        temp,
37224        pxRatio,
37225        windowWidth;
37226
37227      // If we have "srcset", then we need to find first matching "src" value.
37228      // This is necessary, because when you set an src attribute, the browser will preload the image
37229      // before any javascript or even CSS is applied.
37230      if (srcset) {
37231        pxRatio = window.devicePixelRatio || 1;
37232        windowWidth = window.innerWidth * pxRatio;
37233
37234        temp = srcset.split(",").map(function (el) {
37235          var ret = {};
37236
37237          el.trim()
37238            .split(/\s+/)
37239            .forEach(function (el, i) {
37240              var value = parseInt(el.substring(0, el.length - 1), 10);
37241
37242              if (i === 0) {
37243                return (ret.url = el);
37244              }
37245
37246              if (value) {
37247                ret.value = value;
37248                ret.postfix = el[el.length - 1];
37249              }
37250            });
37251
37252          return ret;
37253        });
37254
37255        // Sort by value
37256        temp.sort(function (a, b) {
37257          return a.value - b.value;
37258        });
37259
37260        // Ok, now we have an array of all srcset values
37261        for (var j = 0; j < temp.length; j++) {
37262          var el = temp[j];
37263
37264          if ((el.postfix === "w" && el.value >= windowWidth) || (el.postfix === "x" && el.value >= pxRatio)) {
37265            found = el;
37266            break;
37267          }
37268        }
37269
37270        // If not found, take the last one
37271        if (!found && temp.length) {
37272          found = temp[temp.length - 1];
37273        }
37274
37275        if (found) {
37276          slide.src = found.url;
37277
37278          // If we have default width/height values, we can calculate height for matching source
37279          if (slide.width && slide.height && found.postfix == "w") {
37280            slide.height = (slide.width / slide.height) * found.value;
37281            slide.width = found.value;
37282          }
37283
37284          slide.opts.srcset = srcset;
37285        }
37286      }
37287    },
37288
37289    // Create full-size image
37290    // ======================
37291
37292    setBigImage: function (slide) {
37293      var self = this,
37294        img = document.createElement("img"),
37295        $img = $(img);
37296
37297      slide.$image = $img
37298        .one("error", function () {
37299          self.setError(slide);
37300        })
37301        .one("load", function () {
37302          var sizes;
37303
37304          if (!slide.$ghost) {
37305            self.resolveImageSlideSize(slide, this.naturalWidth, this.naturalHeight);
37306
37307            self.afterLoad(slide);
37308          }
37309
37310          if (self.isClosing) {
37311            return;
37312          }
37313
37314          if (slide.opts.srcset) {
37315            sizes = slide.opts.sizes;
37316
37317            if (!sizes || sizes === "auto") {
37318              sizes =
37319                (slide.width / slide.height > 1 && $W.width() / $W.height() > 1 ? "100" : Math.round((slide.width / slide.height) * 100)) +
37320                "vw";
37321            }
37322
37323            $img.attr("sizes", sizes).attr("srcset", slide.opts.srcset);
37324          }
37325
37326          // Hide temporary image after some delay
37327          if (slide.$ghost) {
37328            setTimeout(function () {
37329              if (slide.$ghost && !self.isClosing) {
37330                slide.$ghost.hide();
37331              }
37332            }, Math.min(300, Math.max(1000, slide.height / 1600)));
37333          }
37334
37335          self.hideLoading(slide);
37336        })
37337        .addClass("fancybox-image")
37338        .attr("src", slide.src)
37339        .appendTo(slide.$content);
37340
37341      if ((img.complete || img.readyState == "complete") && $img.naturalWidth && $img.naturalHeight) {
37342        $img.trigger("load");
37343      } else if (img.error) {
37344        $img.trigger("error");
37345      }
37346    },
37347
37348    // Computes the slide size from image size and maxWidth/maxHeight
37349    // ==============================================================
37350
37351    resolveImageSlideSize: function (slide, imgWidth, imgHeight) {
37352      var maxWidth = parseInt(slide.opts.width, 10),
37353        maxHeight = parseInt(slide.opts.height, 10);
37354
37355      // Sets the default values from the image
37356      slide.width = imgWidth;
37357      slide.height = imgHeight;
37358
37359      if (maxWidth > 0) {
37360        slide.width = maxWidth;
37361        slide.height = Math.floor((maxWidth * imgHeight) / imgWidth);
37362      }
37363
37364      if (maxHeight > 0) {
37365        slide.width = Math.floor((maxHeight * imgWidth) / imgHeight);
37366        slide.height = maxHeight;
37367      }
37368    },
37369
37370    // Create iframe wrapper, iframe and bindings
37371    // ==========================================
37372
37373    setIframe: function (slide) {
37374      var self = this,
37375        opts = slide.opts.iframe,
37376        $slide = slide.$slide,
37377        $iframe;
37378
37379      slide.$content = $('<div class="fancybox-content' + (opts.preload ? " fancybox-is-hidden" : "") + '"></div>')
37380        .css(opts.css)
37381        .appendTo($slide);
37382
37383      $slide.addClass("fancybox-slide--" + slide.contentType);
37384
37385      slide.$iframe = $iframe = $(opts.tpl.replace(/\{rnd\}/g, new Date().getTime()))
37386        .attr(opts.attr)
37387        .appendTo(slide.$content);
37388
37389      if (opts.preload) {
37390        self.showLoading(slide);
37391
37392        // Unfortunately, it is not always possible to determine if iframe is successfully loaded
37393        // (due to browser security policy)
37394
37395        $iframe.on("load.fb error.fb", function (e) {
37396          this.isReady = 1;
37397
37398          slide.$slide.trigger("refresh");
37399
37400          self.afterLoad(slide);
37401        });
37402
37403        // Recalculate iframe content size
37404        // ===============================
37405
37406        $slide.on("refresh.fb", function () {
37407          var $content = slide.$content,
37408            frameWidth = opts.css.width,
37409            frameHeight = opts.css.height,
37410            $contents,
37411            $body;
37412
37413          if ($iframe[0].isReady !== 1) {
37414            return;
37415          }
37416
37417          try {
37418            $contents = $iframe.contents();
37419            $body = $contents.find("body");
37420          } catch (ignore) {}
37421
37422          // Calculate content dimensions, if it is accessible
37423          if ($body && $body.length && $body.children().length) {
37424            // Avoid scrolling to top (if multiple instances)
37425            $slide.css("overflow", "visible");
37426
37427            $content.css({
37428              width: "100%",
37429              "max-width": "100%",
37430              height: "9999px"
37431            });
37432
37433            if (frameWidth === undefined) {
37434              frameWidth = Math.ceil(Math.max($body[0].clientWidth, $body.outerWidth(true)));
37435            }
37436
37437            $content.css("width", frameWidth ? frameWidth : "").css("max-width", "");
37438
37439            if (frameHeight === undefined) {
37440              frameHeight = Math.ceil(Math.max($body[0].clientHeight, $body.outerHeight(true)));
37441            }
37442
37443            $content.css("height", frameHeight ? frameHeight : "");
37444
37445            $slide.css("overflow", "auto");
37446          }
37447
37448          $content.removeClass("fancybox-is-hidden");
37449        });
37450      } else {
37451        self.afterLoad(slide);
37452      }
37453
37454      $iframe.attr("src", slide.src);
37455
37456      // Remove iframe if closing or changing gallery item
37457      $slide.one("onReset", function () {
37458        // This helps IE not to throw errors when closing
37459        try {
37460          $(this)
37461            .find("iframe")
37462            .hide()
37463            .unbind()
37464            .attr("src", "//about:blank");
37465        } catch (ignore) {}
37466
37467        $(this)
37468          .off("refresh.fb")
37469          .empty();
37470
37471        slide.isLoaded = false;
37472        slide.isRevealed = false;
37473      });
37474    },
37475
37476    // Wrap and append content to the slide
37477    // ======================================
37478
37479    setContent: function (slide, content) {
37480      var self = this;
37481
37482      if (self.isClosing) {
37483        return;
37484      }
37485
37486      self.hideLoading(slide);
37487
37488      if (slide.$content) {
37489        $.fancybox.stop(slide.$content);
37490      }
37491
37492      slide.$slide.empty();
37493
37494      // If content is a jQuery object, then it will be moved to the slide.
37495      // The placeholder is created so we will know where to put it back.
37496      if (isQuery(content) && content.parent().length) {
37497        // Make sure content is not already moved to fancyBox
37498        if (content.hasClass("fancybox-content") || content.parent().hasClass("fancybox-content")) {
37499          content.parents(".fancybox-slide").trigger("onReset");
37500        }
37501
37502        // Create temporary element marking original place of the content
37503        slide.$placeholder = $("<div>")
37504          .hide()
37505          .insertAfter(content);
37506
37507        // Make sure content is visible
37508        content.css("display", "inline-block");
37509      } else if (!slide.hasError) {
37510        // If content is just a plain text, try to convert it to html
37511        if ($.type(content) === "string") {
37512          content = $("<div>")
37513            .append($.trim(content))
37514            .contents();
37515        }
37516
37517        // If "filter" option is provided, then filter content
37518        if (slide.opts.filter) {
37519          content = $("<div>")
37520            .html(content)
37521            .find(slide.opts.filter);
37522        }
37523      }
37524
37525      slide.$slide.one("onReset", function () {
37526        // Pause all html5 video/audio
37527        $(this)
37528          .find("video,audio")
37529          .trigger("pause");
37530
37531        // Put content back
37532        if (slide.$placeholder) {
37533          slide.$placeholder.after(content.removeClass("fancybox-content").hide()).remove();
37534
37535          slide.$placeholder = null;
37536        }
37537
37538        // Remove custom close button
37539        if (slide.$smallBtn) {
37540          slide.$smallBtn.remove();
37541
37542          slide.$smallBtn = null;
37543        }
37544
37545        // Remove content and mark slide as not loaded
37546        if (!slide.hasError) {
37547          $(this).empty();
37548
37549          slide.isLoaded = false;
37550          slide.isRevealed = false;
37551        }
37552      });
37553
37554      $(content).appendTo(slide.$slide);
37555
37556      if ($(content).is("video,audio")) {
37557        $(content).addClass("fancybox-video");
37558
37559        $(content).wrap("<div></div>");
37560
37561        slide.contentType = "video";
37562
37563        slide.opts.width = slide.opts.width || $(content).attr("width");
37564        slide.opts.height = slide.opts.height || $(content).attr("height");
37565      }
37566
37567      slide.$content = slide.$slide
37568        .children()
37569        .filter("div,form,main,video,audio,article,.fancybox-content")
37570        .first();
37571
37572      slide.$content.siblings().hide();
37573
37574      // Re-check if there is a valid content
37575      // (in some cases, ajax response can contain various elements or plain text)
37576      if (!slide.$content.length) {
37577        slide.$content = slide.$slide
37578          .wrapInner("<div></div>")
37579          .children()
37580          .first();
37581      }
37582
37583      slide.$content.addClass("fancybox-content");
37584
37585      slide.$slide.addClass("fancybox-slide--" + slide.contentType);
37586
37587      self.afterLoad(slide);
37588    },
37589
37590    // Display error message
37591    // =====================
37592
37593    setError: function (slide) {
37594      slide.hasError = true;
37595
37596      slide.$slide
37597        .trigger("onReset")
37598        .removeClass("fancybox-slide--" + slide.contentType)
37599        .addClass("fancybox-slide--error");
37600
37601      slide.contentType = "html";
37602
37603      this.setContent(slide, this.translate(slide, slide.opts.errorTpl));
37604
37605      if (slide.pos === this.currPos) {
37606        this.isAnimating = false;
37607      }
37608    },
37609
37610    // Show loading icon inside the slide
37611    // ==================================
37612
37613    showLoading: function (slide) {
37614      var self = this;
37615
37616      slide = slide || self.current;
37617
37618      if (slide && !slide.$spinner) {
37619        slide.$spinner = $(self.translate(self, self.opts.spinnerTpl))
37620          .appendTo(slide.$slide)
37621          .hide()
37622          .fadeIn("fast");
37623      }
37624    },
37625
37626    // Remove loading icon from the slide
37627    // ==================================
37628
37629    hideLoading: function (slide) {
37630      var self = this;
37631
37632      slide = slide || self.current;
37633
37634      if (slide && slide.$spinner) {
37635        slide.$spinner.stop().remove();
37636
37637        delete slide.$spinner;
37638      }
37639    },
37640
37641    // Adjustments after slide content has been loaded
37642    // ===============================================
37643
37644    afterLoad: function (slide) {
37645      var self = this;
37646
37647      if (self.isClosing) {
37648        return;
37649      }
37650
37651      slide.isLoading = false;
37652      slide.isLoaded = true;
37653
37654      self.trigger("afterLoad", slide);
37655
37656      self.hideLoading(slide);
37657
37658      // Add small close button
37659      if (slide.opts.smallBtn && (!slide.$smallBtn || !slide.$smallBtn.length)) {
37660        slide.$smallBtn = $(self.translate(slide, slide.opts.btnTpl.smallBtn)).appendTo(slide.$content);
37661      }
37662
37663      // Disable right click
37664      if (slide.opts.protect && slide.$content && !slide.hasError) {
37665        slide.$content.on("contextmenu.fb", function (e) {
37666          if (e.button == 2) {
37667            e.preventDefault();
37668          }
37669
37670          return true;
37671        });
37672
37673        // Add fake element on top of the image
37674        // This makes a bit harder for user to select image
37675        if (slide.type === "image") {
37676          $('<div class="fancybox-spaceball"></div>').appendTo(slide.$content);
37677        }
37678      }
37679
37680      self.adjustCaption(slide);
37681
37682      self.adjustLayout(slide);
37683
37684      if (slide.pos === self.currPos) {
37685        self.updateCursor();
37686      }
37687
37688      self.revealContent(slide);
37689    },
37690
37691    // Prevent caption overlap,
37692    // fix css inconsistency across browsers
37693    // =====================================
37694
37695    adjustCaption: function (slide) {
37696      var self = this,
37697        current = slide || self.current,
37698        caption = current.opts.caption,
37699        preventOverlap = current.opts.preventCaptionOverlap,
37700        $caption = self.$refs.caption,
37701        $clone,
37702        captionH = false;
37703
37704      $caption.toggleClass("fancybox-caption--separate", preventOverlap);
37705
37706      if (preventOverlap && caption && caption.length) {
37707        if (current.pos !== self.currPos) {
37708          $clone = $caption.clone().appendTo($caption.parent());
37709
37710          $clone
37711            .children()
37712            .eq(0)
37713            .empty()
37714            .html(caption);
37715
37716          captionH = $clone.outerHeight(true);
37717
37718          $clone.empty().remove();
37719        } else if (self.$caption) {
37720          captionH = self.$caption.outerHeight(true);
37721        }
37722
37723        current.$slide.css("padding-bottom", captionH || "");
37724      }
37725    },
37726
37727    // Simple hack to fix inconsistency across browsers, described here (affects Edge, too):
37728    // https://bugzilla.mozilla.org/show_bug.cgi?id=748518
37729    // ====================================================================================
37730
37731    adjustLayout: function (slide) {
37732      var self = this,
37733        current = slide || self.current,
37734        scrollHeight,
37735        marginBottom,
37736        inlinePadding,
37737        actualPadding;
37738
37739      if (current.isLoaded && current.opts.disableLayoutFix !== true) {
37740        current.$content.css("margin-bottom", "");
37741
37742        // If we would always set margin-bottom for the content,
37743        // then it would potentially break vertical align
37744        if (current.$content.outerHeight() > current.$slide.height() + 0.5) {
37745          inlinePadding = current.$slide[0].style["padding-bottom"];
37746          actualPadding = current.$slide.css("padding-bottom");
37747
37748          if (parseFloat(actualPadding) > 0) {
37749            scrollHeight = current.$slide[0].scrollHeight;
37750
37751            current.$slide.css("padding-bottom", 0);
37752
37753            if (Math.abs(scrollHeight - current.$slide[0].scrollHeight) < 1) {
37754              marginBottom = actualPadding;
37755            }
37756
37757            current.$slide.css("padding-bottom", inlinePadding);
37758          }
37759        }
37760
37761        current.$content.css("margin-bottom", marginBottom);
37762      }
37763    },
37764
37765    // Make content visible
37766    // This method is called right after content has been loaded or
37767    // user navigates gallery and transition should start
37768    // ============================================================
37769
37770    revealContent: function (slide) {
37771      var self = this,
37772        $slide = slide.$slide,
37773        end = false,
37774        start = false,
37775        isMoved = self.isMoved(slide),
37776        isRevealed = slide.isRevealed,
37777        effect,
37778        effectClassName,
37779        duration,
37780        opacity;
37781
37782      slide.isRevealed = true;
37783
37784      effect = slide.opts[self.firstRun ? "animationEffect" : "transitionEffect"];
37785      duration = slide.opts[self.firstRun ? "animationDuration" : "transitionDuration"];
37786
37787      duration = parseInt(slide.forcedDuration === undefined ? duration : slide.forcedDuration, 10);
37788
37789      if (isMoved || slide.pos !== self.currPos || !duration) {
37790        effect = false;
37791      }
37792
37793      // Check if can zoom
37794      if (effect === "zoom") {
37795        if (slide.pos === self.currPos && duration && slide.type === "image" && !slide.hasError && (start = self.getThumbPos(slide))) {
37796          end = self.getFitPos(slide);
37797        } else {
37798          effect = "fade";
37799        }
37800      }
37801
37802      // Zoom animation
37803      // ==============
37804      if (effect === "zoom") {
37805        self.isAnimating = true;
37806
37807        end.scaleX = end.width / start.width;
37808        end.scaleY = end.height / start.height;
37809
37810        // Check if we need to animate opacity
37811        opacity = slide.opts.zoomOpacity;
37812
37813        if (opacity == "auto") {
37814          opacity = Math.abs(slide.width / slide.height - start.width / start.height) > 0.1;
37815        }
37816
37817        if (opacity) {
37818          start.opacity = 0.1;
37819          end.opacity = 1;
37820        }
37821
37822        // Draw image at start position
37823        $.fancybox.setTranslate(slide.$content.removeClass("fancybox-is-hidden"), start);
37824
37825        forceRedraw(slide.$content);
37826
37827        // Start animation
37828        $.fancybox.animate(slide.$content, end, duration, function () {
37829          self.isAnimating = false;
37830
37831          self.complete();
37832        });
37833
37834        return;
37835      }
37836
37837      self.updateSlide(slide);
37838
37839      // Simply show content if no effect
37840      // ================================
37841      if (!effect) {
37842        slide.$content.removeClass("fancybox-is-hidden");
37843
37844        if (!isRevealed && isMoved && slide.type === "image" && !slide.hasError) {
37845          slide.$content.hide().fadeIn("fast");
37846        }
37847
37848        if (slide.pos === self.currPos) {
37849          self.complete();
37850        }
37851
37852        return;
37853      }
37854
37855      // Prepare for CSS transiton
37856      // =========================
37857      $.fancybox.stop($slide);
37858
37859      //effectClassName = "fancybox-animated fancybox-slide--" + (slide.pos >= self.prevPos ? "next" : "previous") + " fancybox-fx-" + effect;
37860      effectClassName = "fancybox-slide--" + (slide.pos >= self.prevPos ? "next" : "previous") + " fancybox-animated fancybox-fx-" + effect;
37861
37862      $slide.addClass(effectClassName).removeClass("fancybox-slide--current"); //.addClass(effectClassName);
37863
37864      slide.$content.removeClass("fancybox-is-hidden");
37865
37866      // Force reflow
37867      forceRedraw($slide);
37868
37869      if (slide.type !== "image") {
37870        slide.$content.hide().show(0);
37871      }
37872
37873      $.fancybox.animate(
37874        $slide,
37875        "fancybox-slide--current",
37876        duration,
37877        function () {
37878          $slide.removeClass(effectClassName).css({
37879            transform: "",
37880            opacity: ""
37881          });
37882
37883          if (slide.pos === self.currPos) {
37884            self.complete();
37885          }
37886        },
37887        true
37888      );
37889    },
37890
37891    // Check if we can and have to zoom from thumbnail
37892    //================================================
37893
37894    getThumbPos: function (slide) {
37895      var rez = false,
37896        $thumb = slide.$thumb,
37897        thumbPos,
37898        btw,
37899        brw,
37900        bbw,
37901        blw;
37902
37903      if (!$thumb || !inViewport($thumb[0])) {
37904        return false;
37905      }
37906
37907      thumbPos = $.fancybox.getTranslate($thumb);
37908
37909      btw = parseFloat($thumb.css("border-top-width") || 0);
37910      brw = parseFloat($thumb.css("border-right-width") || 0);
37911      bbw = parseFloat($thumb.css("border-bottom-width") || 0);
37912      blw = parseFloat($thumb.css("border-left-width") || 0);
37913
37914      rez = {
37915        top: thumbPos.top + btw,
37916        left: thumbPos.left + blw,
37917        width: thumbPos.width - brw - blw,
37918        height: thumbPos.height - btw - bbw,
37919        scaleX: 1,
37920        scaleY: 1
37921      };
37922
37923      return thumbPos.width > 0 && thumbPos.height > 0 ? rez : false;
37924    },
37925
37926    // Final adjustments after current gallery item is moved to position
37927    // and it`s content is loaded
37928    // ==================================================================
37929
37930    complete: function () {
37931      var self = this,
37932        current = self.current,
37933        slides = {},
37934        $el;
37935
37936      if (self.isMoved() || !current.isLoaded) {
37937        return;
37938      }
37939
37940      if (!current.isComplete) {
37941        current.isComplete = true;
37942
37943        current.$slide.siblings().trigger("onReset");
37944
37945        self.preload("inline");
37946
37947        // Trigger any CSS transiton inside the slide
37948        forceRedraw(current.$slide);
37949
37950        current.$slide.addClass("fancybox-slide--complete");
37951
37952        // Remove unnecessary slides
37953        $.each(self.slides, function (key, slide) {
37954          if (slide.pos >= self.currPos - 1 && slide.pos <= self.currPos + 1) {
37955            slides[slide.pos] = slide;
37956          } else if (slide) {
37957            $.fancybox.stop(slide.$slide);
37958
37959            slide.$slide.off().remove();
37960          }
37961        });
37962
37963        self.slides = slides;
37964      }
37965
37966      self.isAnimating = false;
37967
37968      self.updateCursor();
37969
37970      self.trigger("afterShow");
37971
37972      // Autoplay first html5 video/audio
37973      if (!!current.opts.video.autoStart) {
37974        current.$slide
37975          .find("video,audio")
37976          .filter(":visible:first")
37977          .trigger("play")
37978          .one("ended", function () {
37979            if (Document.exitFullscreen) {
37980              Document.exitFullscreen();
37981            } else if (this.webkitExitFullscreen) {
37982              this.webkitExitFullscreen();
37983            }
37984
37985            self.next();
37986          });
37987      }
37988
37989      // Try to focus on the first focusable element
37990      if (current.opts.autoFocus && current.contentType === "html") {
37991        // Look for the first input with autofocus attribute
37992        $el = current.$content.find("input[autofocus]:enabled:visible:first");
37993
37994        if ($el.length) {
37995          $el.trigger("focus");
37996        } else {
37997          self.focus(null, true);
37998        }
37999      }
38000
38001      // Avoid jumping
38002      current.$slide.scrollTop(0).scrollLeft(0);
38003    },
38004
38005    // Preload next and previous slides
38006    // ================================
38007
38008    preload: function (type) {
38009      var self = this,
38010        prev,
38011        next;
38012
38013      if (self.group.length < 2) {
38014        return;
38015      }
38016
38017      next = self.slides[self.currPos + 1];
38018      prev = self.slides[self.currPos - 1];
38019
38020      if (prev && prev.type === type) {
38021        self.loadSlide(prev);
38022      }
38023
38024      if (next && next.type === type) {
38025        self.loadSlide(next);
38026      }
38027    },
38028
38029    // Try to find and focus on the first focusable element
38030    // ====================================================
38031
38032    focus: function (e, firstRun) {
38033      var self = this,
38034        focusableStr = [
38035          "a[href]",
38036          "area[href]",
38037          'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',
38038          "select:not([disabled]):not([aria-hidden])",
38039          "textarea:not([disabled]):not([aria-hidden])",
38040          "button:not([disabled]):not([aria-hidden])",
38041          "iframe",
38042          "object",
38043          "embed",
38044          "video",
38045          "audio",
38046          "[contenteditable]",
38047          '[tabindex]:not([tabindex^="-"])'
38048        ].join(","),
38049        focusableItems,
38050        focusedItemIndex;
38051
38052      if (self.isClosing) {
38053        return;
38054      }
38055
38056      if (e || !self.current || !self.current.isComplete) {
38057        // Focus on any element inside fancybox
38058        focusableItems = self.$refs.container.find("*:visible");
38059      } else {
38060        // Focus inside current slide
38061        focusableItems = self.current.$slide.find("*:visible" + (firstRun ? ":not(.fancybox-close-small)" : ""));
38062      }
38063
38064      focusableItems = focusableItems.filter(focusableStr).filter(function () {
38065        return $(this).css("visibility") !== "hidden" && !$(this).hasClass("disabled");
38066      });
38067
38068      if (focusableItems.length) {
38069        focusedItemIndex = focusableItems.index(document.activeElement);
38070
38071        if (e && e.shiftKey) {
38072          // Back tab
38073          if (focusedItemIndex < 0 || focusedItemIndex == 0) {
38074            e.preventDefault();
38075
38076            focusableItems.eq(focusableItems.length - 1).trigger("focus");
38077          }
38078        } else {
38079          // Outside or Forward tab
38080          if (focusedItemIndex < 0 || focusedItemIndex == focusableItems.length - 1) {
38081            if (e) {
38082              e.preventDefault();
38083            }
38084
38085            focusableItems.eq(0).trigger("focus");
38086          }
38087        }
38088      } else {
38089        self.$refs.container.trigger("focus");
38090      }
38091    },
38092
38093    // Activates current instance - brings container to the front and enables keyboard,
38094    // notifies other instances about deactivating
38095    // =================================================================================
38096
38097    activate: function () {
38098      var self = this;
38099
38100      // Deactivate all instances
38101      $(".fancybox-container").each(function () {
38102        var instance = $(this).data("FancyBox");
38103
38104        // Skip self and closing instances
38105        if (instance && instance.id !== self.id && !instance.isClosing) {
38106          instance.trigger("onDeactivate");
38107
38108          instance.removeEvents();
38109
38110          instance.isVisible = false;
38111        }
38112      });
38113
38114      self.isVisible = true;
38115
38116      if (self.current || self.isIdle) {
38117        self.update();
38118
38119        self.updateControls();
38120      }
38121
38122      self.trigger("onActivate");
38123
38124      self.addEvents();
38125    },
38126
38127    // Start closing procedure
38128    // This will start "zoom-out" animation if needed and clean everything up afterwards
38129    // =================================================================================
38130
38131    close: function (e, d) {
38132      var self = this,
38133        current = self.current,
38134        effect,
38135        duration,
38136        $content,
38137        domRect,
38138        opacity,
38139        start,
38140        end;
38141
38142      var done = function () {
38143        self.cleanUp(e);
38144      };
38145
38146      if (self.isClosing) {
38147        return false;
38148      }
38149
38150      self.isClosing = true;
38151
38152      // If beforeClose callback prevents closing, make sure content is centered
38153      if (self.trigger("beforeClose", e) === false) {
38154        self.isClosing = false;
38155
38156        requestAFrame(function () {
38157          self.update();
38158        });
38159
38160        return false;
38161      }
38162
38163      // Remove all events
38164      // If there are multiple instances, they will be set again by "activate" method
38165      self.removeEvents();
38166
38167      $content = current.$content;
38168      effect = current.opts.animationEffect;
38169      duration = $.isNumeric(d) ? d : effect ? current.opts.animationDuration : 0;
38170
38171      current.$slide.removeClass("fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated");
38172
38173      if (e !== true) {
38174        $.fancybox.stop(current.$slide);
38175      } else {
38176        effect = false;
38177      }
38178
38179      // Remove other slides
38180      current.$slide
38181        .siblings()
38182        .trigger("onReset")
38183        .remove();
38184
38185      // Trigger animations
38186      if (duration) {
38187        self.$refs.container
38188          .removeClass("fancybox-is-open")
38189          .addClass("fancybox-is-closing")
38190          .css("transition-duration", duration + "ms");
38191      }
38192
38193      // Clean up
38194      self.hideLoading(current);
38195
38196      self.hideControls(true);
38197
38198      self.updateCursor();
38199
38200      // Check if possible to zoom-out
38201      if (
38202        effect === "zoom" &&
38203        !($content && duration && current.type === "image" && !self.isMoved() && !current.hasError && (end = self.getThumbPos(current)))
38204      ) {
38205        effect = "fade";
38206      }
38207
38208      if (effect === "zoom") {
38209        $.fancybox.stop($content);
38210
38211        domRect = $.fancybox.getTranslate($content);
38212
38213        start = {
38214          top: domRect.top,
38215          left: domRect.left,
38216          scaleX: domRect.width / end.width,
38217          scaleY: domRect.height / end.height,
38218          width: end.width,
38219          height: end.height
38220        };
38221
38222        // Check if we need to animate opacity
38223        opacity = current.opts.zoomOpacity;
38224
38225        if (opacity == "auto") {
38226          opacity = Math.abs(current.width / current.height - end.width / end.height) > 0.1;
38227        }
38228
38229        if (opacity) {
38230          end.opacity = 0;
38231        }
38232
38233        $.fancybox.setTranslate($content, start);
38234
38235        forceRedraw($content);
38236
38237        $.fancybox.animate($content, end, duration, done);
38238
38239        return true;
38240      }
38241
38242      if (effect && duration) {
38243        $.fancybox.animate(
38244          current.$slide.addClass("fancybox-slide--previous").removeClass("fancybox-slide--current"),
38245          "fancybox-animated fancybox-fx-" + effect,
38246          duration,
38247          done
38248        );
38249      } else {
38250        // If skip animation
38251        if (e === true) {
38252          setTimeout(done, duration);
38253        } else {
38254          done();
38255        }
38256      }
38257
38258      return true;
38259    },
38260
38261    // Final adjustments after removing the instance
38262    // =============================================
38263
38264    cleanUp: function (e) {
38265      var self = this,
38266        instance,
38267        $focus = self.current.opts.$orig,
38268        x,
38269        y;
38270
38271      self.current.$slide.trigger("onReset");
38272
38273      self.$refs.container.empty().remove();
38274
38275      self.trigger("afterClose", e);
38276
38277      // Place back focus
38278      if (!!self.current.opts.backFocus) {
38279        if (!$focus || !$focus.length || !$focus.is(":visible")) {
38280          $focus = self.$trigger;
38281        }
38282
38283        if ($focus && $focus.length) {
38284          x = window.scrollX;
38285          y = window.scrollY;
38286
38287          $focus.trigger("focus");
38288
38289          $("html, body")
38290            .scrollTop(y)
38291            .scrollLeft(x);
38292        }
38293      }
38294
38295      self.current = null;
38296
38297      // Check if there are other instances
38298      instance = $.fancybox.getInstance();
38299
38300      if (instance) {
38301        instance.activate();
38302      } else {
38303        $("body").removeClass("fancybox-active compensate-for-scrollbar");
38304
38305        $("#fancybox-style-noscroll").remove();
38306      }
38307    },
38308
38309    // Call callback and trigger an event
38310    // ==================================
38311
38312    trigger: function (name, slide) {
38313      var args = Array.prototype.slice.call(arguments, 1),
38314        self = this,
38315        obj = slide && slide.opts ? slide : self.current,
38316        rez;
38317
38318      if (obj) {
38319        args.unshift(obj);
38320      } else {
38321        obj = self;
38322      }
38323
38324      args.unshift(self);
38325
38326      if ($.isFunction(obj.opts[name])) {
38327        rez = obj.opts[name].apply(obj, args);
38328      }
38329
38330      if (rez === false) {
38331        return rez;
38332      }
38333
38334      if (name === "afterClose" || !self.$refs) {
38335        $D.trigger(name + ".fb", args);
38336      } else {
38337        self.$refs.container.trigger(name + ".fb", args);
38338      }
38339    },
38340
38341    // Update infobar values, navigation button states and reveal caption
38342    // ==================================================================
38343
38344    updateControls: function () {
38345      var self = this,
38346        current = self.current,
38347        index = current.index,
38348        $container = self.$refs.container,
38349        $caption = self.$refs.caption,
38350        caption = current.opts.caption;
38351
38352      // Recalculate content dimensions
38353      current.$slide.trigger("refresh");
38354
38355      // Set caption
38356      if (caption && caption.length) {
38357        self.$caption = $caption;
38358
38359        $caption
38360          .children()
38361          .eq(0)
38362          .html(caption);
38363      } else {
38364        self.$caption = null;
38365      }
38366
38367      if (!self.hasHiddenControls && !self.isIdle) {
38368        self.showControls();
38369      }
38370
38371      // Update info and navigation elements
38372      $container.find("[data-fancybox-count]").html(self.group.length);
38373      $container.find("[data-fancybox-index]").html(index + 1);
38374
38375      $container.find("[data-fancybox-prev]").prop("disabled", !current.opts.loop && index <= 0);
38376      $container.find("[data-fancybox-next]").prop("disabled", !current.opts.loop && index >= self.group.length - 1);
38377
38378      if (current.type === "image") {
38379        // Re-enable buttons; update download button source
38380        $container
38381          .find("[data-fancybox-zoom]")
38382          .show()
38383          .end()
38384          .find("[data-fancybox-download]")
38385          .attr("href", current.opts.image.src || current.src)
38386          .show();
38387      } else if (current.opts.toolbar) {
38388        $container.find("[data-fancybox-download],[data-fancybox-zoom]").hide();
38389      }
38390
38391      // Make sure focus is not on disabled button/element
38392      if ($(document.activeElement).is(":hidden,[disabled]")) {
38393        self.$refs.container.trigger("focus");
38394      }
38395    },
38396
38397    // Hide toolbar and caption
38398    // ========================
38399
38400    hideControls: function (andCaption) {
38401      var self = this,
38402        arr = ["infobar", "toolbar", "nav"];
38403
38404      if (andCaption || !self.current.opts.preventCaptionOverlap) {
38405        arr.push("caption");
38406      }
38407
38408      this.$refs.container.removeClass(
38409        arr
38410        .map(function (i) {
38411          return "fancybox-show-" + i;
38412        })
38413        .join(" ")
38414      );
38415
38416      this.hasHiddenControls = true;
38417    },
38418
38419    showControls: function () {
38420      var self = this,
38421        opts = self.current ? self.current.opts : self.opts,
38422        $container = self.$refs.container;
38423
38424      self.hasHiddenControls = false;
38425      self.idleSecondsCounter = 0;
38426
38427      $container
38428        .toggleClass("fancybox-show-toolbar", !!(opts.toolbar && opts.buttons))
38429        .toggleClass("fancybox-show-infobar", !!(opts.infobar && self.group.length > 1))
38430        .toggleClass("fancybox-show-caption", !!self.$caption)
38431        .toggleClass("fancybox-show-nav", !!(opts.arrows && self.group.length > 1))
38432        .toggleClass("fancybox-is-modal", !!opts.modal);
38433    },
38434
38435    // Toggle toolbar and caption
38436    // ==========================
38437
38438    toggleControls: function () {
38439      if (this.hasHiddenControls) {
38440        this.showControls();
38441      } else {
38442        this.hideControls();
38443      }
38444    }
38445  });
38446
38447  $.fancybox = {
38448    version: "3.5.7",
38449    defaults: defaults,
38450
38451    // Get current instance and execute a command.
38452    //
38453    // Examples of usage:
38454    //
38455    //   $instance = $.fancybox.getInstance();
38456    //   $.fancybox.getInstance().jumpTo( 1 );
38457    //   $.fancybox.getInstance( 'jumpTo', 1 );
38458    //   $.fancybox.getInstance( function() {
38459    //       console.info( this.currIndex );
38460    //   });
38461    // ======================================================
38462
38463    getInstance: function (command) {
38464      var instance = $('.fancybox-container:not(".fancybox-is-closing"):last').data("FancyBox"),
38465        args = Array.prototype.slice.call(arguments, 1);
38466
38467      if (instance instanceof FancyBox) {
38468        if ($.type(command) === "string") {
38469          instance[command].apply(instance, args);
38470        } else if ($.type(command) === "function") {
38471          command.apply(instance, args);
38472        }
38473
38474        return instance;
38475      }
38476
38477      return false;
38478    },
38479
38480    // Create new instance
38481    // ===================
38482
38483    open: function (items, opts, index) {
38484      return new FancyBox(items, opts, index);
38485    },
38486
38487    // Close current or all instances
38488    // ==============================
38489
38490    close: function (all) {
38491      var instance = this.getInstance();
38492
38493      if (instance) {
38494        instance.close();
38495
38496        // Try to find and close next instance
38497        if (all === true) {
38498          this.close(all);
38499        }
38500      }
38501    },
38502
38503    // Close all instances and unbind all events
38504    // =========================================
38505
38506    destroy: function () {
38507      this.close(true);
38508
38509      $D.add("body").off("click.fb-start", "**");
38510    },
38511
38512    // Try to detect mobile devices
38513    // ============================
38514
38515    isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
38516
38517    // Detect if 'translate3d' support is available
38518    // ============================================
38519
38520    use3d: (function () {
38521      var div = document.createElement("div");
38522
38523      return (
38524        window.getComputedStyle &&
38525        window.getComputedStyle(div) &&
38526        window.getComputedStyle(div).getPropertyValue("transform") &&
38527        !(document.documentMode && document.documentMode < 11)
38528      );
38529    })(),
38530
38531    // Helper function to get current visual state of an element
38532    // returns array[ top, left, horizontal-scale, vertical-scale, opacity ]
38533    // =====================================================================
38534
38535    getTranslate: function ($el) {
38536      var domRect;
38537
38538      if (!$el || !$el.length) {
38539        return false;
38540      }
38541
38542      domRect = $el[0].getBoundingClientRect();
38543
38544      return {
38545        top: domRect.top || 0,
38546        left: domRect.left || 0,
38547        width: domRect.width,
38548        height: domRect.height,
38549        opacity: parseFloat($el.css("opacity"))
38550      };
38551    },
38552
38553    // Shortcut for setting "translate3d" properties for element
38554    // Can set be used to set opacity, too
38555    // ========================================================
38556
38557    setTranslate: function ($el, props) {
38558      var str = "",
38559        css = {};
38560
38561      if (!$el || !props) {
38562        return;
38563      }
38564
38565      if (props.left !== undefined || props.top !== undefined) {
38566        str =
38567          (props.left === undefined ? $el.position().left : props.left) +
38568          "px, " +
38569          (props.top === undefined ? $el.position().top : props.top) +
38570          "px";
38571
38572        if (this.use3d) {
38573          str = "translate3d(" + str + ", 0px)";
38574        } else {
38575          str = "translate(" + str + ")";
38576        }
38577      }
38578
38579      if (props.scaleX !== undefined && props.scaleY !== undefined) {
38580        str += " scale(" + props.scaleX + ", " + props.scaleY + ")";
38581      } else if (props.scaleX !== undefined) {
38582        str += " scaleX(" + props.scaleX + ")";
38583      }
38584
38585      if (str.length) {
38586        css.transform = str;
38587      }
38588
38589      if (props.opacity !== undefined) {
38590        css.opacity = props.opacity;
38591      }
38592
38593      if (props.width !== undefined) {
38594        css.width = props.width;
38595      }
38596
38597      if (props.height !== undefined) {
38598        css.height = props.height;
38599      }
38600
38601      return $el.css(css);
38602    },
38603
38604    // Simple CSS transition handler
38605    // =============================
38606
38607    animate: function ($el, to, duration, callback, leaveAnimationName) {
38608      var self = this,
38609        from;
38610
38611      if ($.isFunction(duration)) {
38612        callback = duration;
38613        duration = null;
38614      }
38615
38616      self.stop($el);
38617
38618      from = self.getTranslate($el);
38619
38620      $el.on(transitionEnd, function (e) {
38621        // Skip events from child elements and z-index change
38622        if (e && e.originalEvent && (!$el.is(e.originalEvent.target) || e.originalEvent.propertyName == "z-index")) {
38623          return;
38624        }
38625
38626        self.stop($el);
38627
38628        if ($.isNumeric(duration)) {
38629          $el.css("transition-duration", "");
38630        }
38631
38632        if ($.isPlainObject(to)) {
38633          if (to.scaleX !== undefined && to.scaleY !== undefined) {
38634            self.setTranslate($el, {
38635              top: to.top,
38636              left: to.left,
38637              width: from.width * to.scaleX,
38638              height: from.height * to.scaleY,
38639              scaleX: 1,
38640              scaleY: 1
38641            });
38642          }
38643        } else if (leaveAnimationName !== true) {
38644          $el.removeClass(to);
38645        }
38646
38647        if ($.isFunction(callback)) {
38648          callback(e);
38649        }
38650      });
38651
38652      if ($.isNumeric(duration)) {
38653        $el.css("transition-duration", duration + "ms");
38654      }
38655
38656      // Start animation by changing CSS properties or class name
38657      if ($.isPlainObject(to)) {
38658        if (to.scaleX !== undefined && to.scaleY !== undefined) {
38659          delete to.width;
38660          delete to.height;
38661
38662          if ($el.parent().hasClass("fancybox-slide--image")) {
38663            $el.parent().addClass("fancybox-is-scaling");
38664          }
38665        }
38666
38667        $.fancybox.setTranslate($el, to);
38668      } else {
38669        $el.addClass(to);
38670      }
38671
38672      // Make sure that `transitionend` callback gets fired
38673      $el.data(
38674        "timer",
38675        setTimeout(function () {
38676          $el.trigger(transitionEnd);
38677        }, duration + 33)
38678      );
38679    },
38680
38681    stop: function ($el, callCallback) {
38682      if ($el && $el.length) {
38683        clearTimeout($el.data("timer"));
38684
38685        if (callCallback) {
38686          $el.trigger(transitionEnd);
38687        }
38688
38689        $el.off(transitionEnd).css("transition-duration", "");
38690
38691        $el.parent().removeClass("fancybox-is-scaling");
38692      }
38693    }
38694  };
38695
38696  // Default click handler for "fancyboxed" links
38697  // ============================================
38698
38699  function _run(e, opts) {
38700    var items = [],
38701      index = 0,
38702      $target,
38703      value,
38704      instance;
38705
38706    // Avoid opening multiple times
38707    if (e && e.isDefaultPrevented()) {
38708      return;
38709    }
38710
38711    e.preventDefault();
38712
38713    opts = opts || {};
38714
38715    if (e && e.data) {
38716      opts = mergeOpts(e.data.options, opts);
38717    }
38718
38719    $target = opts.$target || $(e.currentTarget).trigger("blur");
38720    instance = $.fancybox.getInstance();
38721
38722    if (instance && instance.$trigger && instance.$trigger.is($target)) {
38723      return;
38724    }
38725
38726    if (opts.selector) {
38727      items = $(opts.selector);
38728    } else {
38729      // Get all related items and find index for clicked one
38730      value = $target.attr("data-fancybox") || "";
38731
38732      if (value) {
38733        items = e.data ? e.data.items : [];
38734        items = items.length ? items.filter('[data-fancybox="' + value + '"]') : $('[data-fancybox="' + value + '"]');
38735      } else {
38736        items = [$target];
38737      }
38738    }
38739
38740    index = $(items).index($target);
38741
38742    // Sometimes current item can not be found
38743    if (index < 0) {
38744      index = 0;
38745    }
38746
38747    instance = $.fancybox.open(items, opts, index);
38748
38749    // Save last active element
38750    instance.$trigger = $target;
38751  }
38752
38753  // Create a jQuery plugin
38754  // ======================
38755
38756  $.fn.fancybox = function (options) {
38757    var selector;
38758
38759    options = options || {};
38760    selector = options.selector || false;
38761
38762    if (selector) {
38763      // Use body element instead of document so it executes first
38764      $("body")
38765        .off("click.fb-start", selector)
38766        .on("click.fb-start", selector, {
38767          options: options
38768        }, _run);
38769    } else {
38770      this.off("click.fb-start").on(
38771        "click.fb-start", {
38772          items: this,
38773          options: options
38774        },
38775        _run
38776      );
38777    }
38778
38779    return this;
38780  };
38781
38782  // Self initializing plugin for all elements having `data-fancybox` attribute
38783  // ==========================================================================
38784
38785  $D.on("click.fb-start", "[data-fancybox]", _run);
38786
38787  // Enable "trigger elements"
38788  // =========================
38789
38790  $D.on("click.fb-start", "[data-fancybox-trigger]", function (e) {
38791    $('[data-fancybox="' + $(this).attr("data-fancybox-trigger") + '"]')
38792      .eq($(this).attr("data-fancybox-index") || 0)
38793      .trigger("click.fb-start", {
38794        $trigger: $(this)
38795      });
38796  });
38797
38798  // Track focus event for better accessibility styling
38799  // ==================================================
38800  (function () {
38801    var buttonStr = ".fancybox-button",
38802      focusStr = "fancybox-focus",
38803      $pressed = null;
38804
38805    $D.on("mousedown mouseup focus blur", buttonStr, function (e) {
38806      switch (e.type) {
38807        case "mousedown":
38808          $pressed = $(this);
38809          break;
38810        case "mouseup":
38811          $pressed = null;
38812          break;
38813        case "focusin":
38814          $(buttonStr).removeClass(focusStr);
38815
38816          if (!$(this).is($pressed) && !$(this).is("[disabled]")) {
38817            $(this).addClass(focusStr);
38818          }
38819          break;
38820        case "focusout":
38821          $(buttonStr).removeClass(focusStr);
38822          break;
38823      }
38824    });
38825  })();
38826})(window, document, jQuery);
38827// ==========================================================================
38828//
38829// Media
38830// Adds additional media type support
38831//
38832// ==========================================================================
38833(function ($) {
38834  "use strict";
38835
38836  // Object containing properties for each media type
38837  var defaults = {
38838    youtube: {
38839      matcher: /(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i,
38840      params: {
38841        autoplay: 1,
38842        autohide: 1,
38843        fs: 1,
38844        rel: 0,
38845        hd: 1,
38846        wmode: "transparent",
38847        enablejsapi: 1,
38848        html5: 1
38849      },
38850      paramPlace: 8,
38851      type: "iframe",
38852      url: "https://www.youtube-nocookie.com/embed/$4",
38853      thumb: "https://img.youtube.com/vi/$4/hqdefault.jpg"
38854    },
38855
38856    vimeo: {
38857      matcher: /^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/,
38858      params: {
38859        autoplay: 1,
38860        hd: 1,
38861        show_title: 1,
38862        show_byline: 1,
38863        show_portrait: 0,
38864        fullscreen: 1
38865      },
38866      paramPlace: 3,
38867      type: "iframe",
38868      url: "//player.vimeo.com/video/$2"
38869    },
38870
38871    instagram: {
38872      matcher: /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,
38873      type: "image",
38874      url: "//$1/p/$2/media/?size=l"
38875    },
38876
38877    // Examples:
38878    // http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
38879    // https://www.google.com/maps/@37.7852006,-122.4146355,14.65z
38880    // https://www.google.com/maps/@52.2111123,2.9237542,6.61z?hl=en
38881    // https://www.google.com/maps/place/Googleplex/@37.4220041,-122.0833494,17z/data=!4m5!3m4!1s0x0:0x6c296c66619367e0!8m2!3d37.4219998!4d-122.0840572
38882    gmap_place: {
38883      matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(((maps\/(place\/(.*)\/)?\@(.*),(\d+.?\d+?)z))|(\?ll=))(.*)?/i,
38884      type: "iframe",
38885      url: function (rez) {
38886        return (
38887          "//maps.google." +
38888          rez[2] +
38889          "/?ll=" +
38890          (rez[9] ? rez[9] + "&z=" + Math.floor(rez[10]) + (rez[12] ? rez[12].replace(/^\//, "&") : "") : rez[12] + "").replace(/\?/, "&") +
38891          "&output=" +
38892          (rez[12] && rez[12].indexOf("layer=c") > 0 ? "svembed" : "embed")
38893        );
38894      }
38895    },
38896
38897    // Examples:
38898    // https://www.google.com/maps/search/Empire+State+Building/
38899    // https://www.google.com/maps/search/?api=1&query=centurylink+field
38900    // https://www.google.com/maps/search/?api=1&query=47.5951518,-122.3316393
38901    gmap_search: {
38902      matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(maps\/search\/)(.*)/i,
38903      type: "iframe",
38904      url: function (rez) {
38905        return "//maps.google." + rez[2] + "/maps?q=" + rez[5].replace("query=", "q=").replace("api=1", "") + "&output=embed";
38906      }
38907    }
38908  };
38909
38910  // Formats matching url to final form
38911  var format = function (url, rez, params) {
38912    if (!url) {
38913      return;
38914    }
38915
38916    params = params || "";
38917
38918    if ($.type(params) === "object") {
38919      params = $.param(params, true);
38920    }
38921
38922    $.each(rez, function (key, value) {
38923      url = url.replace("$" + key, value || "");
38924    });
38925
38926    if (params.length) {
38927      url += (url.indexOf("?") > 0 ? "&" : "?") + params;
38928    }
38929
38930    return url;
38931  };
38932
38933  $(document).on("objectNeedsType.fb", function (e, instance, item) {
38934    var url = item.src || "",
38935      type = false,
38936      media,
38937      thumb,
38938      rez,
38939      params,
38940      urlParams,
38941      paramObj,
38942      provider;
38943
38944    media = $.extend(true, {}, defaults, item.opts.media);
38945
38946    // Look for any matching media type
38947    $.each(media, function (providerName, providerOpts) {
38948      rez = url.match(providerOpts.matcher);
38949
38950      if (!rez) {
38951        return;
38952      }
38953
38954      type = providerOpts.type;
38955      provider = providerName;
38956      paramObj = {};
38957
38958      if (providerOpts.paramPlace && rez[providerOpts.paramPlace]) {
38959        urlParams = rez[providerOpts.paramPlace];
38960
38961        if (urlParams[0] == "?") {
38962          urlParams = urlParams.substring(1);
38963        }
38964
38965        urlParams = urlParams.split("&");
38966
38967        for (var m = 0; m < urlParams.length; ++m) {
38968          var p = urlParams[m].split("=", 2);
38969
38970          if (p.length == 2) {
38971            paramObj[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
38972          }
38973        }
38974      }
38975
38976      params = $.extend(true, {}, providerOpts.params, item.opts[providerName], paramObj);
38977
38978      url =
38979        $.type(providerOpts.url) === "function" ? providerOpts.url.call(this, rez, params, item) : format(providerOpts.url, rez, params);
38980
38981      thumb =
38982        $.type(providerOpts.thumb) === "function" ? providerOpts.thumb.call(this, rez, params, item) : format(providerOpts.thumb, rez);
38983
38984      if (providerName === "youtube") {
38985        url = url.replace(/&t=((\d+)m)?(\d+)s/, function (match, p1, m, s) {
38986          return "&start=" + ((m ? parseInt(m, 10) * 60 : 0) + parseInt(s, 10));
38987        });
38988      } else if (providerName === "vimeo") {
38989        url = url.replace("&%23", "#");
38990      }
38991
38992      return false;
38993    });
38994
38995    // If it is found, then change content type and update the url
38996
38997    if (type) {
38998      if (!item.opts.thumb && !(item.opts.$thumb && item.opts.$thumb.length)) {
38999        item.opts.thumb = thumb;
39000      }
39001
39002      if (type === "iframe") {
39003        item.opts = $.extend(true, item.opts, {
39004          iframe: {
39005            preload: false,
39006            attr: {
39007              scrolling: "no"
39008            }
39009          }
39010        });
39011      }
39012
39013      $.extend(item, {
39014        type: type,
39015        src: url,
39016        origSrc: item.src,
39017        contentSource: provider,
39018        contentType: type === "image" ? "image" : provider == "gmap_place" || provider == "gmap_search" ? "map" : "video"
39019      });
39020    } else if (url) {
39021      item.type = item.opts.defaultType;
39022    }
39023  });
39024
39025  // Load YouTube/Video API on request to detect when video finished playing
39026  var VideoAPILoader = {
39027    youtube: {
39028      src: "https://www.youtube.com/iframe_api",
39029      class: "YT",
39030      loading: false,
39031      loaded: false
39032    },
39033
39034    vimeo: {
39035      src: "https://player.vimeo.com/api/player.js",
39036      class: "Vimeo",
39037      loading: false,
39038      loaded: false
39039    },
39040
39041    load: function (vendor) {
39042      var _this = this,
39043        script;
39044
39045      if (this[vendor].loaded) {
39046        setTimeout(function () {
39047          _this.done(vendor);
39048        });
39049        return;
39050      }
39051
39052      if (this[vendor].loading) {
39053        return;
39054      }
39055
39056      this[vendor].loading = true;
39057
39058      script = document.createElement("script");
39059      script.type = "text/javascript";
39060      script.src = this[vendor].src;
39061
39062      if (vendor === "youtube") {
39063        window.onYouTubeIframeAPIReady = function () {
39064          _this[vendor].loaded = true;
39065          _this.done(vendor);
39066        };
39067      } else {
39068        script.onload = function () {
39069          _this[vendor].loaded = true;
39070          _this.done(vendor);
39071        };
39072      }
39073
39074      document.body.appendChild(script);
39075    },
39076    done: function (vendor) {
39077      var instance, $el, player;
39078
39079      if (vendor === "youtube") {
39080        delete window.onYouTubeIframeAPIReady;
39081      }
39082
39083      instance = $.fancybox.getInstance();
39084
39085      if (instance) {
39086        $el = instance.current.$content.find("iframe");
39087
39088        if (vendor === "youtube" && YT !== undefined && YT) {
39089          player = new YT.Player($el.attr("id"), {
39090            events: {
39091              onStateChange: function (e) {
39092                if (e.data == 0) {
39093                  instance.next();
39094                }
39095              }
39096            }
39097          });
39098        } else if (vendor === "vimeo" && Vimeo !== undefined && Vimeo) {
39099          player = new Vimeo.Player($el);
39100
39101          player.on("ended", function () {
39102            instance.next();
39103          });
39104        }
39105      }
39106    }
39107  };
39108
39109  $(document).on({
39110    "afterShow.fb": function (e, instance, current) {
39111      if (instance.group.length > 1 && (current.contentSource === "youtube" || current.contentSource === "vimeo")) {
39112        VideoAPILoader.load(current.contentSource);
39113      }
39114    }
39115  });
39116})(jQuery);
39117// ==========================================================================
39118//
39119// Guestures
39120// Adds touch guestures, handles click and tap events
39121//
39122// ==========================================================================
39123(function (window, document, $) {
39124  "use strict";
39125
39126  var requestAFrame = (function () {
39127    return (
39128      window.requestAnimationFrame ||
39129      window.webkitRequestAnimationFrame ||
39130      window.mozRequestAnimationFrame ||
39131      window.oRequestAnimationFrame ||
39132      // if all else fails, use setTimeout
39133      function (callback) {
39134        return window.setTimeout(callback, 1000 / 60);
39135      }
39136    );
39137  })();
39138
39139  var cancelAFrame = (function () {
39140    return (
39141      window.cancelAnimationFrame ||
39142      window.webkitCancelAnimationFrame ||
39143      window.mozCancelAnimationFrame ||
39144      window.oCancelAnimationFrame ||
39145      function (id) {
39146        window.clearTimeout(id);
39147      }
39148    );
39149  })();
39150
39151  var getPointerXY = function (e) {
39152    var result = [];
39153
39154    e = e.originalEvent || e || window.e;
39155    e = e.touches && e.touches.length ? e.touches : e.changedTouches && e.changedTouches.length ? e.changedTouches : [e];
39156
39157    for (var key in e) {
39158      if (e[key].pageX) {
39159        result.push({
39160          x: e[key].pageX,
39161          y: e[key].pageY
39162        });
39163      } else if (e[key].clientX) {
39164        result.push({
39165          x: e[key].clientX,
39166          y: e[key].clientY
39167        });
39168      }
39169    }
39170
39171    return result;
39172  };
39173
39174  var distance = function (point2, point1, what) {
39175    if (!point1 || !point2) {
39176      return 0;
39177    }
39178
39179    if (what === "x") {
39180      return point2.x - point1.x;
39181    } else if (what === "y") {
39182      return point2.y - point1.y;
39183    }
39184
39185    return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
39186  };
39187
39188  var isClickable = function ($el) {
39189    if (
39190      $el.is('a,area,button,[role="button"],input,label,select,summary,textarea,video,audio,iframe') ||
39191      $.isFunction($el.get(0).onclick) ||
39192      $el.data("selectable")
39193    ) {
39194      return true;
39195    }
39196
39197    // Check for attributes like data-fancybox-next or data-fancybox-close
39198    for (var i = 0, atts = $el[0].attributes, n = atts.length; i < n; i++) {
39199      if (atts[i].nodeName.substr(0, 14) === "data-fancybox-") {
39200        return true;
39201      }
39202    }
39203
39204    return false;
39205  };
39206
39207  var hasScrollbars = function (el) {
39208    var overflowY = window.getComputedStyle(el)["overflow-y"],
39209      overflowX = window.getComputedStyle(el)["overflow-x"],
39210      vertical = (overflowY === "scroll" || overflowY === "auto") && el.scrollHeight > el.clientHeight,
39211      horizontal = (overflowX === "scroll" || overflowX === "auto") && el.scrollWidth > el.clientWidth;
39212
39213    return vertical || horizontal;
39214  };
39215
39216  var isScrollable = function ($el) {
39217    var rez = false;
39218
39219    while (true) {
39220      rez = hasScrollbars($el.get(0));
39221
39222      if (rez) {
39223        break;
39224      }
39225
39226      $el = $el.parent();
39227
39228      if (!$el.length || $el.hasClass("fancybox-stage") || $el.is("body")) {
39229        break;
39230      }
39231    }
39232
39233    return rez;
39234  };
39235
39236  var Guestures = function (instance) {
39237    var self = this;
39238
39239    self.instance = instance;
39240
39241    self.$bg = instance.$refs.bg;
39242    self.$stage = instance.$refs.stage;
39243    self.$container = instance.$refs.container;
39244
39245    self.destroy();
39246
39247    self.$container.on("touchstart.fb.touch mousedown.fb.touch", $.proxy(self, "ontouchstart"));
39248  };
39249
39250  Guestures.prototype.destroy = function () {
39251    var self = this;
39252
39253    self.$container.off(".fb.touch");
39254
39255    $(document).off(".fb.touch");
39256
39257    if (self.requestId) {
39258      cancelAFrame(self.requestId);
39259      self.requestId = null;
39260    }
39261
39262    if (self.tapped) {
39263      clearTimeout(self.tapped);
39264      self.tapped = null;
39265    }
39266  };
39267
39268  Guestures.prototype.ontouchstart = function (e) {
39269    var self = this,
39270      $target = $(e.target),
39271      instance = self.instance,
39272      current = instance.current,
39273      $slide = current.$slide,
39274      $content = current.$content,
39275      isTouchDevice = e.type == "touchstart";
39276
39277    // Do not respond to both (touch and mouse) events
39278    if (isTouchDevice) {
39279      self.$container.off("mousedown.fb.touch");
39280    }
39281
39282    // Ignore right click
39283    if (e.originalEvent && e.originalEvent.button == 2) {
39284      return;
39285    }
39286
39287    // Ignore taping on links, buttons, input elements
39288    if (!$slide.length || !$target.length || isClickable($target) || isClickable($target.parent())) {
39289      return;
39290    }
39291    // Ignore clicks on the scrollbar
39292    if (!$target.is("img") && e.originalEvent.clientX > $target[0].clientWidth + $target.offset().left) {
39293      return;
39294    }
39295
39296    // Ignore clicks while zooming or closing
39297    if (!current || instance.isAnimating || current.$slide.hasClass("fancybox-animated")) {
39298      e.stopPropagation();
39299      e.preventDefault();
39300
39301      return;
39302    }
39303
39304    self.realPoints = self.startPoints = getPointerXY(e);
39305
39306    if (!self.startPoints.length) {
39307      return;
39308    }
39309
39310    // Allow other scripts to catch touch event if "touch" is set to false
39311    if (current.touch) {
39312      e.stopPropagation();
39313    }
39314
39315    self.startEvent = e;
39316
39317    self.canTap = true;
39318    self.$target = $target;
39319    self.$content = $content;
39320    self.opts = current.opts.touch;
39321
39322    self.isPanning = false;
39323    self.isSwiping = false;
39324    self.isZooming = false;
39325    self.isScrolling = false;
39326    self.canPan = instance.canPan();
39327
39328    self.startTime = new Date().getTime();
39329    self.distanceX = self.distanceY = self.distance = 0;
39330
39331    self.canvasWidth = Math.round($slide[0].clientWidth);
39332    self.canvasHeight = Math.round($slide[0].clientHeight);
39333
39334    self.contentLastPos = null;
39335    self.contentStartPos = $.fancybox.getTranslate(self.$content) || {
39336      top: 0,
39337      left: 0
39338    };
39339    self.sliderStartPos = $.fancybox.getTranslate($slide);
39340
39341    // Since position will be absolute, but we need to make it relative to the stage
39342    self.stagePos = $.fancybox.getTranslate(instance.$refs.stage);
39343
39344    self.sliderStartPos.top -= self.stagePos.top;
39345    self.sliderStartPos.left -= self.stagePos.left;
39346
39347    self.contentStartPos.top -= self.stagePos.top;
39348    self.contentStartPos.left -= self.stagePos.left;
39349
39350    $(document)
39351      .off(".fb.touch")
39352      .on(isTouchDevice ? "touchend.fb.touch touchcancel.fb.touch" : "mouseup.fb.touch mouseleave.fb.touch", $.proxy(self, "ontouchend"))
39353      .on(isTouchDevice ? "touchmove.fb.touch" : "mousemove.fb.touch", $.proxy(self, "ontouchmove"));
39354
39355    if ($.fancybox.isMobile) {
39356      document.addEventListener("scroll", self.onscroll, true);
39357    }
39358
39359    // Skip if clicked outside the sliding area
39360    if (!(self.opts || self.canPan) || !($target.is(self.$stage) || self.$stage.find($target).length)) {
39361      if ($target.is(".fancybox-image")) {
39362        e.preventDefault();
39363      }
39364
39365      if (!($.fancybox.isMobile && $target.parents(".fancybox-caption").length)) {
39366        return;
39367      }
39368    }
39369
39370    self.isScrollable = isScrollable($target) || isScrollable($target.parent());
39371
39372    // Check if element is scrollable and try to prevent default behavior (scrolling)
39373    if (!($.fancybox.isMobile && self.isScrollable)) {
39374      e.preventDefault();
39375    }
39376
39377    // One finger or mouse click - swipe or pan an image
39378    if (self.startPoints.length === 1 || current.hasError) {
39379      if (self.canPan) {
39380        $.fancybox.stop(self.$content);
39381
39382        self.isPanning = true;
39383      } else {
39384        self.isSwiping = true;
39385      }
39386
39387      self.$container.addClass("fancybox-is-grabbing");
39388    }
39389
39390    // Two fingers - zoom image
39391    if (self.startPoints.length === 2 && current.type === "image" && (current.isLoaded || current.$ghost)) {
39392      self.canTap = false;
39393      self.isSwiping = false;
39394      self.isPanning = false;
39395
39396      self.isZooming = true;
39397
39398      $.fancybox.stop(self.$content);
39399
39400      self.centerPointStartX = (self.startPoints[0].x + self.startPoints[1].x) * 0.5 - $(window).scrollLeft();
39401      self.centerPointStartY = (self.startPoints[0].y + self.startPoints[1].y) * 0.5 - $(window).scrollTop();
39402
39403      self.percentageOfImageAtPinchPointX = (self.centerPointStartX - self.contentStartPos.left) / self.contentStartPos.width;
39404      self.percentageOfImageAtPinchPointY = (self.centerPointStartY - self.contentStartPos.top) / self.contentStartPos.height;
39405
39406      self.startDistanceBetweenFingers = distance(self.startPoints[0], self.startPoints[1]);
39407    }
39408  };
39409
39410  Guestures.prototype.onscroll = function (e) {
39411    var self = this;
39412
39413    self.isScrolling = true;
39414
39415    document.removeEventListener("scroll", self.onscroll, true);
39416  };
39417
39418  Guestures.prototype.ontouchmove = function (e) {
39419    var self = this;
39420
39421    // Make sure user has not released over iframe or disabled element
39422    if (e.originalEvent.buttons !== undefined && e.originalEvent.buttons === 0) {
39423      self.ontouchend(e);
39424      return;
39425    }
39426
39427    if (self.isScrolling) {
39428      self.canTap = false;
39429      return;
39430    }
39431
39432    self.newPoints = getPointerXY(e);
39433
39434    if (!(self.opts || self.canPan) || !self.newPoints.length || !self.newPoints.length) {
39435      return;
39436    }
39437
39438    if (!(self.isSwiping && self.isSwiping === true)) {
39439      e.preventDefault();
39440    }
39441
39442    self.distanceX = distance(self.newPoints[0], self.startPoints[0], "x");
39443    self.distanceY = distance(self.newPoints[0], self.startPoints[0], "y");
39444
39445    self.distance = distance(self.newPoints[0], self.startPoints[0]);
39446
39447    // Skip false ontouchmove events (Chrome)
39448    if (self.distance > 0) {
39449      if (self.isSwiping) {
39450        self.onSwipe(e);
39451      } else if (self.isPanning) {
39452        self.onPan();
39453      } else if (self.isZooming) {
39454        self.onZoom();
39455      }
39456    }
39457  };
39458
39459  Guestures.prototype.onSwipe = function (e) {
39460    var self = this,
39461      instance = self.instance,
39462      swiping = self.isSwiping,
39463      left = self.sliderStartPos.left || 0,
39464      angle;
39465
39466    // If direction is not yet determined
39467    if (swiping === true) {
39468      // We need at least 10px distance to correctly calculate an angle
39469      if (Math.abs(self.distance) > 10) {
39470        self.canTap = false;
39471
39472        if (instance.group.length < 2 && self.opts.vertical) {
39473          self.isSwiping = "y";
39474        } else if (instance.isDragging || self.opts.vertical === false || (self.opts.vertical === "auto" && $(window).width() > 800)) {
39475          self.isSwiping = "x";
39476        } else {
39477          angle = Math.abs((Math.atan2(self.distanceY, self.distanceX) * 180) / Math.PI);
39478
39479          self.isSwiping = angle > 45 && angle < 135 ? "y" : "x";
39480        }
39481
39482        if (self.isSwiping === "y" && $.fancybox.isMobile && self.isScrollable) {
39483          self.isScrolling = true;
39484
39485          return;
39486        }
39487
39488        instance.isDragging = self.isSwiping;
39489
39490        // Reset points to avoid jumping, because we dropped first swipes to calculate the angle
39491        self.startPoints = self.newPoints;
39492
39493        $.each(instance.slides, function (index, slide) {
39494          var slidePos, stagePos;
39495
39496          $.fancybox.stop(slide.$slide);
39497
39498          slidePos = $.fancybox.getTranslate(slide.$slide);
39499          stagePos = $.fancybox.getTranslate(instance.$refs.stage);
39500
39501          slide.$slide
39502            .css({
39503              transform: "",
39504              opacity: "",
39505              "transition-duration": ""
39506            })
39507            .removeClass("fancybox-animated")
39508            .removeClass(function (index, className) {
39509              return (className.match(/(^|\s)fancybox-fx-\S+/g) || []).join(" ");
39510            });
39511
39512          if (slide.pos === instance.current.pos) {
39513            self.sliderStartPos.top = slidePos.top - stagePos.top;
39514            self.sliderStartPos.left = slidePos.left - stagePos.left;
39515          }
39516
39517          $.fancybox.setTranslate(slide.$slide, {
39518            top: slidePos.top - stagePos.top,
39519            left: slidePos.left - stagePos.left
39520          });
39521        });
39522
39523        // Stop slideshow
39524        if (instance.SlideShow && instance.SlideShow.isActive) {
39525          instance.SlideShow.stop();
39526        }
39527      }
39528
39529      return;
39530    }
39531
39532    // Sticky edges
39533    if (swiping == "x") {
39534      if (
39535        self.distanceX > 0 &&
39536        (self.instance.group.length < 2 || (self.instance.current.index === 0 && !self.instance.current.opts.loop))
39537      ) {
39538        left = left + Math.pow(self.distanceX, 0.8);
39539      } else if (
39540        self.distanceX < 0 &&
39541        (self.instance.group.length < 2 ||
39542          (self.instance.current.index === self.instance.group.length - 1 && !self.instance.current.opts.loop))
39543      ) {
39544        left = left - Math.pow(-self.distanceX, 0.8);
39545      } else {
39546        left = left + self.distanceX;
39547      }
39548    }
39549
39550    self.sliderLastPos = {
39551      top: swiping == "x" ? 0 : self.sliderStartPos.top + self.distanceY,
39552      left: left
39553    };
39554
39555    if (self.requestId) {
39556      cancelAFrame(self.requestId);
39557
39558      self.requestId = null;
39559    }
39560
39561    self.requestId = requestAFrame(function () {
39562      if (self.sliderLastPos) {
39563        $.each(self.instance.slides, function (index, slide) {
39564          var pos = slide.pos - self.instance.currPos;
39565
39566          $.fancybox.setTranslate(slide.$slide, {
39567            top: self.sliderLastPos.top,
39568            left: self.sliderLastPos.left + pos * self.canvasWidth + pos * slide.opts.gutter
39569          });
39570        });
39571
39572        self.$container.addClass("fancybox-is-sliding");
39573      }
39574    });
39575  };
39576
39577  Guestures.prototype.onPan = function () {
39578    var self = this;
39579
39580    // Prevent accidental movement (sometimes, when tapping casually, finger can move a bit)
39581    if (distance(self.newPoints[0], self.realPoints[0]) < ($.fancybox.isMobile ? 10 : 5)) {
39582      self.startPoints = self.newPoints;
39583      return;
39584    }
39585
39586    self.canTap = false;
39587
39588    self.contentLastPos = self.limitMovement();
39589
39590    if (self.requestId) {
39591      cancelAFrame(self.requestId);
39592    }
39593
39594    self.requestId = requestAFrame(function () {
39595      $.fancybox.setTranslate(self.$content, self.contentLastPos);
39596    });
39597  };
39598
39599  // Make panning sticky to the edges
39600  Guestures.prototype.limitMovement = function () {
39601    var self = this;
39602
39603    var canvasWidth = self.canvasWidth;
39604    var canvasHeight = self.canvasHeight;
39605
39606    var distanceX = self.distanceX;
39607    var distanceY = self.distanceY;
39608
39609    var contentStartPos = self.contentStartPos;
39610
39611    var currentOffsetX = contentStartPos.left;
39612    var currentOffsetY = contentStartPos.top;
39613
39614    var currentWidth = contentStartPos.width;
39615    var currentHeight = contentStartPos.height;
39616
39617    var minTranslateX, minTranslateY, maxTranslateX, maxTranslateY, newOffsetX, newOffsetY;
39618
39619    if (currentWidth > canvasWidth) {
39620      newOffsetX = currentOffsetX + distanceX;
39621    } else {
39622      newOffsetX = currentOffsetX;
39623    }
39624
39625    newOffsetY = currentOffsetY + distanceY;
39626
39627    // Slow down proportionally to traveled distance
39628    minTranslateX = Math.max(0, canvasWidth * 0.5 - currentWidth * 0.5);
39629    minTranslateY = Math.max(0, canvasHeight * 0.5 - currentHeight * 0.5);
39630
39631    maxTranslateX = Math.min(canvasWidth - currentWidth, canvasWidth * 0.5 - currentWidth * 0.5);
39632    maxTranslateY = Math.min(canvasHeight - currentHeight, canvasHeight * 0.5 - currentHeight * 0.5);
39633
39634    //   ->
39635    if (distanceX > 0 && newOffsetX > minTranslateX) {
39636      newOffsetX = minTranslateX - 1 + Math.pow(-minTranslateX + currentOffsetX + distanceX, 0.8) || 0;
39637    }
39638
39639    //    <-
39640    if (distanceX < 0 && newOffsetX < maxTranslateX) {
39641      newOffsetX = maxTranslateX + 1 - Math.pow(maxTranslateX - currentOffsetX - distanceX, 0.8) || 0;
39642    }
39643
39644    //   \/
39645    if (distanceY > 0 && newOffsetY > minTranslateY) {
39646      newOffsetY = minTranslateY - 1 + Math.pow(-minTranslateY + currentOffsetY + distanceY, 0.8) || 0;
39647    }
39648
39649    //   /\
39650    if (distanceY < 0 && newOffsetY < maxTranslateY) {
39651      newOffsetY = maxTranslateY + 1 - Math.pow(maxTranslateY - currentOffsetY - distanceY, 0.8) || 0;
39652    }
39653
39654    return {
39655      top: newOffsetY,
39656      left: newOffsetX
39657    };
39658  };
39659
39660  Guestures.prototype.limitPosition = function (newOffsetX, newOffsetY, newWidth, newHeight) {
39661    var self = this;
39662
39663    var canvasWidth = self.canvasWidth;
39664    var canvasHeight = self.canvasHeight;
39665
39666    if (newWidth > canvasWidth) {
39667      newOffsetX = newOffsetX > 0 ? 0 : newOffsetX;
39668      newOffsetX = newOffsetX < canvasWidth - newWidth ? canvasWidth - newWidth : newOffsetX;
39669    } else {
39670      // Center horizontally
39671      newOffsetX = Math.max(0, canvasWidth / 2 - newWidth / 2);
39672    }
39673
39674    if (newHeight > canvasHeight) {
39675      newOffsetY = newOffsetY > 0 ? 0 : newOffsetY;
39676      newOffsetY = newOffsetY < canvasHeight - newHeight ? canvasHeight - newHeight : newOffsetY;
39677    } else {
39678      // Center vertically
39679      newOffsetY = Math.max(0, canvasHeight / 2 - newHeight / 2);
39680    }
39681
39682    return {
39683      top: newOffsetY,
39684      left: newOffsetX
39685    };
39686  };
39687
39688  Guestures.prototype.onZoom = function () {
39689    var self = this;
39690
39691    // Calculate current distance between points to get pinch ratio and new width and height
39692    var contentStartPos = self.contentStartPos;
39693
39694    var currentWidth = contentStartPos.width;
39695    var currentHeight = contentStartPos.height;
39696
39697    var currentOffsetX = contentStartPos.left;
39698    var currentOffsetY = contentStartPos.top;
39699
39700    var endDistanceBetweenFingers = distance(self.newPoints[0], self.newPoints[1]);
39701
39702    var pinchRatio = endDistanceBetweenFingers / self.startDistanceBetweenFingers;
39703
39704    var newWidth = Math.floor(currentWidth * pinchRatio);
39705    var newHeight = Math.floor(currentHeight * pinchRatio);
39706
39707    // This is the translation due to pinch-zooming
39708    var translateFromZoomingX = (currentWidth - newWidth) * self.percentageOfImageAtPinchPointX;
39709    var translateFromZoomingY = (currentHeight - newHeight) * self.percentageOfImageAtPinchPointY;
39710
39711    // Point between the two touches
39712    var centerPointEndX = (self.newPoints[0].x + self.newPoints[1].x) / 2 - $(window).scrollLeft();
39713    var centerPointEndY = (self.newPoints[0].y + self.newPoints[1].y) / 2 - $(window).scrollTop();
39714
39715    // And this is the translation due to translation of the centerpoint
39716    // between the two fingers
39717    var translateFromTranslatingX = centerPointEndX - self.centerPointStartX;
39718    var translateFromTranslatingY = centerPointEndY - self.centerPointStartY;
39719
39720    // The new offset is the old/current one plus the total translation
39721    var newOffsetX = currentOffsetX + (translateFromZoomingX + translateFromTranslatingX);
39722    var newOffsetY = currentOffsetY + (translateFromZoomingY + translateFromTranslatingY);
39723
39724    var newPos = {
39725      top: newOffsetY,
39726      left: newOffsetX,
39727      scaleX: pinchRatio,
39728      scaleY: pinchRatio
39729    };
39730
39731    self.canTap = false;
39732
39733    self.newWidth = newWidth;
39734    self.newHeight = newHeight;
39735
39736    self.contentLastPos = newPos;
39737
39738    if (self.requestId) {
39739      cancelAFrame(self.requestId);
39740    }
39741
39742    self.requestId = requestAFrame(function () {
39743      $.fancybox.setTranslate(self.$content, self.contentLastPos);
39744    });
39745  };
39746
39747  Guestures.prototype.ontouchend = function (e) {
39748    var self = this;
39749
39750    var swiping = self.isSwiping;
39751    var panning = self.isPanning;
39752    var zooming = self.isZooming;
39753    var scrolling = self.isScrolling;
39754
39755    self.endPoints = getPointerXY(e);
39756    self.dMs = Math.max(new Date().getTime() - self.startTime, 1);
39757
39758    self.$container.removeClass("fancybox-is-grabbing");
39759
39760    $(document).off(".fb.touch");
39761
39762    document.removeEventListener("scroll", self.onscroll, true);
39763
39764    if (self.requestId) {
39765      cancelAFrame(self.requestId);
39766
39767      self.requestId = null;
39768    }
39769
39770    self.isSwiping = false;
39771    self.isPanning = false;
39772    self.isZooming = false;
39773    self.isScrolling = false;
39774
39775    self.instance.isDragging = false;
39776
39777    if (self.canTap) {
39778      return self.onTap(e);
39779    }
39780
39781    self.speed = 100;
39782
39783    // Speed in px/ms
39784    self.velocityX = (self.distanceX / self.dMs) * 0.5;
39785    self.velocityY = (self.distanceY / self.dMs) * 0.5;
39786
39787    if (panning) {
39788      self.endPanning();
39789    } else if (zooming) {
39790      self.endZooming();
39791    } else {
39792      self.endSwiping(swiping, scrolling);
39793    }
39794
39795    return;
39796  };
39797
39798  Guestures.prototype.endSwiping = function (swiping, scrolling) {
39799    var self = this,
39800      ret = false,
39801      len = self.instance.group.length,
39802      distanceX = Math.abs(self.distanceX),
39803      canAdvance = swiping == "x" && len > 1 && ((self.dMs > 130 && distanceX > 10) || distanceX > 50),
39804      speedX = 300;
39805
39806    self.sliderLastPos = null;
39807
39808    // Close if swiped vertically / navigate if horizontally
39809    if (swiping == "y" && !scrolling && Math.abs(self.distanceY) > 50) {
39810      // Continue vertical movement
39811      $.fancybox.animate(
39812        self.instance.current.$slide, {
39813          top: self.sliderStartPos.top + self.distanceY + self.velocityY * 150,
39814          opacity: 0
39815        },
39816        200
39817      );
39818      ret = self.instance.close(true, 250);
39819    } else if (canAdvance && self.distanceX > 0) {
39820      ret = self.instance.previous(speedX);
39821    } else if (canAdvance && self.distanceX < 0) {
39822      ret = self.instance.next(speedX);
39823    }
39824
39825    if (ret === false && (swiping == "x" || swiping == "y")) {
39826      self.instance.centerSlide(200);
39827    }
39828
39829    self.$container.removeClass("fancybox-is-sliding");
39830  };
39831
39832  // Limit panning from edges
39833  // ========================
39834  Guestures.prototype.endPanning = function () {
39835    var self = this,
39836      newOffsetX,
39837      newOffsetY,
39838      newPos;
39839
39840    if (!self.contentLastPos) {
39841      return;
39842    }
39843
39844    if (self.opts.momentum === false || self.dMs > 350) {
39845      newOffsetX = self.contentLastPos.left;
39846      newOffsetY = self.contentLastPos.top;
39847    } else {
39848      // Continue movement
39849      newOffsetX = self.contentLastPos.left + self.velocityX * 500;
39850      newOffsetY = self.contentLastPos.top + self.velocityY * 500;
39851    }
39852
39853    newPos = self.limitPosition(newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height);
39854
39855    newPos.width = self.contentStartPos.width;
39856    newPos.height = self.contentStartPos.height;
39857
39858    $.fancybox.animate(self.$content, newPos, 366);
39859  };
39860
39861  Guestures.prototype.endZooming = function () {
39862    var self = this;
39863
39864    var current = self.instance.current;
39865
39866    var newOffsetX, newOffsetY, newPos, reset;
39867
39868    var newWidth = self.newWidth;
39869    var newHeight = self.newHeight;
39870
39871    if (!self.contentLastPos) {
39872      return;
39873    }
39874
39875    newOffsetX = self.contentLastPos.left;
39876    newOffsetY = self.contentLastPos.top;
39877
39878    reset = {
39879      top: newOffsetY,
39880      left: newOffsetX,
39881      width: newWidth,
39882      height: newHeight,
39883      scaleX: 1,
39884      scaleY: 1
39885    };
39886
39887    // Reset scalex/scaleY values; this helps for perfomance and does not break animation
39888    $.fancybox.setTranslate(self.$content, reset);
39889
39890    if (newWidth < self.canvasWidth && newHeight < self.canvasHeight) {
39891      self.instance.scaleToFit(150);
39892    } else if (newWidth > current.width || newHeight > current.height) {
39893      self.instance.scaleToActual(self.centerPointStartX, self.centerPointStartY, 150);
39894    } else {
39895      newPos = self.limitPosition(newOffsetX, newOffsetY, newWidth, newHeight);
39896
39897      $.fancybox.animate(self.$content, newPos, 150);
39898    }
39899  };
39900
39901  Guestures.prototype.onTap = function (e) {
39902    var self = this;
39903    var $target = $(e.target);
39904
39905    var instance = self.instance;
39906    var current = instance.current;
39907
39908    var endPoints = (e && getPointerXY(e)) || self.startPoints;
39909
39910    var tapX = endPoints[0] ? endPoints[0].x - $(window).scrollLeft() - self.stagePos.left : 0;
39911    var tapY = endPoints[0] ? endPoints[0].y - $(window).scrollTop() - self.stagePos.top : 0;
39912
39913    var where;
39914
39915    var process = function (prefix) {
39916      var action = current.opts[prefix];
39917
39918      if ($.isFunction(action)) {
39919        action = action.apply(instance, [current, e]);
39920      }
39921
39922      if (!action) {
39923        return;
39924      }
39925
39926      switch (action) {
39927        case "close":
39928          instance.close(self.startEvent);
39929
39930          break;
39931
39932        case "toggleControls":
39933          instance.toggleControls();
39934
39935          break;
39936
39937        case "next":
39938          instance.next();
39939
39940          break;
39941
39942        case "nextOrClose":
39943          if (instance.group.length > 1) {
39944            instance.next();
39945          } else {
39946            instance.close(self.startEvent);
39947          }
39948
39949          break;
39950
39951        case "zoom":
39952          if (current.type == "image" && (current.isLoaded || current.$ghost)) {
39953            if (instance.canPan()) {
39954              instance.scaleToFit();
39955            } else if (instance.isScaledDown()) {
39956              instance.scaleToActual(tapX, tapY);
39957            } else if (instance.group.length < 2) {
39958              instance.close(self.startEvent);
39959            }
39960          }
39961
39962          break;
39963      }
39964    };
39965
39966    // Ignore right click
39967    if (e.originalEvent && e.originalEvent.button == 2) {
39968      return;
39969    }
39970
39971    // Skip if clicked on the scrollbar
39972    if (!$target.is("img") && tapX > $target[0].clientWidth + $target.offset().left) {
39973      return;
39974    }
39975
39976    // Check where is clicked
39977    if ($target.is(".fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container")) {
39978      where = "Outside";
39979    } else if ($target.is(".fancybox-slide")) {
39980      where = "Slide";
39981    } else if (
39982      instance.current.$content &&
39983      instance.current.$content
39984      .find($target)
39985      .addBack()
39986      .filter($target).length
39987    ) {
39988      where = "Content";
39989    } else {
39990      return;
39991    }
39992
39993    // Check if this is a double tap
39994    if (self.tapped) {
39995      // Stop previously created single tap
39996      clearTimeout(self.tapped);
39997      self.tapped = null;
39998
39999      // Skip if distance between taps is too big
40000      if (Math.abs(tapX - self.tapX) > 50 || Math.abs(tapY - self.tapY) > 50) {
40001        return this;
40002      }
40003
40004      // OK, now we assume that this is a double-tap
40005      process("dblclick" + where);
40006    } else {
40007      // Single tap will be processed if user has not clicked second time within 300ms
40008      // or there is no need to wait for double-tap
40009      self.tapX = tapX;
40010      self.tapY = tapY;
40011
40012      if (current.opts["dblclick" + where] && current.opts["dblclick" + where] !== current.opts["click" + where]) {
40013        self.tapped = setTimeout(function () {
40014          self.tapped = null;
40015
40016          if (!instance.isAnimating) {
40017            process("click" + where);
40018          }
40019        }, 500);
40020      } else {
40021        process("click" + where);
40022      }
40023    }
40024
40025    return this;
40026  };
40027
40028  $(document)
40029    .on("onActivate.fb", function (e, instance) {
40030      if (instance && !instance.Guestures) {
40031        instance.Guestures = new Guestures(instance);
40032      }
40033    })
40034    .on("beforeClose.fb", function (e, instance) {
40035      if (instance && instance.Guestures) {
40036        instance.Guestures.destroy();
40037      }
40038    });
40039})(window, document, jQuery);
40040// ==========================================================================
40041//
40042// SlideShow
40043// Enables slideshow functionality
40044//
40045// Example of usage:
40046// $.fancybox.getInstance().SlideShow.start()
40047//
40048// ==========================================================================
40049(function (document, $) {
40050  "use strict";
40051
40052  $.extend(true, $.fancybox.defaults, {
40053    btnTpl: {
40054      slideShow: '<button data-fancybox-play class="fancybox-button fancybox-button--play" title="{{PLAY_START}}">' +
40055        '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.5 5.4v13.2l11-6.6z"/></svg>' +
40056        '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.33 5.75h2.2v12.5h-2.2V5.75zm5.15 0h2.2v12.5h-2.2V5.75z"/></svg>' +
40057        "</button>"
40058    },
40059    slideShow: {
40060      autoStart: false,
40061      speed: 3000,
40062      progress: true
40063    }
40064  });
40065
40066  var SlideShow = function (instance) {
40067    this.instance = instance;
40068    this.init();
40069  };
40070
40071  $.extend(SlideShow.prototype, {
40072    timer: null,
40073    isActive: false,
40074    $button: null,
40075
40076    init: function () {
40077      var self = this,
40078        instance = self.instance,
40079        opts = instance.group[instance.currIndex].opts.slideShow;
40080
40081      self.$button = instance.$refs.toolbar.find("[data-fancybox-play]").on("click", function () {
40082        self.toggle();
40083      });
40084
40085      if (instance.group.length < 2 || !opts) {
40086        self.$button.hide();
40087      } else if (opts.progress) {
40088        self.$progress = $('<div class="fancybox-progress"></div>').appendTo(instance.$refs.inner);
40089      }
40090    },
40091
40092    set: function (force) {
40093      var self = this,
40094        instance = self.instance,
40095        current = instance.current;
40096
40097      // Check if reached last element
40098      if (current && (force === true || current.opts.loop || instance.currIndex < instance.group.length - 1)) {
40099        if (self.isActive && current.contentType !== "video") {
40100          if (self.$progress) {
40101            $.fancybox.animate(self.$progress.show(), {
40102              scaleX: 1
40103            }, current.opts.slideShow.speed);
40104          }
40105
40106          self.timer = setTimeout(function () {
40107            if (!instance.current.opts.loop && instance.current.index == instance.group.length - 1) {
40108              instance.jumpTo(0);
40109            } else {
40110              instance.next();
40111            }
40112          }, current.opts.slideShow.speed);
40113        }
40114      } else {
40115        self.stop();
40116        instance.idleSecondsCounter = 0;
40117        instance.showControls();
40118      }
40119    },
40120
40121    clear: function () {
40122      var self = this;
40123
40124      clearTimeout(self.timer);
40125
40126      self.timer = null;
40127
40128      if (self.$progress) {
40129        self.$progress.removeAttr("style").hide();
40130      }
40131    },
40132
40133    start: function () {
40134      var self = this,
40135        current = self.instance.current;
40136
40137      if (current) {
40138        self.$button
40139          .attr("title", (current.opts.i18n[current.opts.lang] || current.opts.i18n.en).PLAY_STOP)
40140          .removeClass("fancybox-button--play")
40141          .addClass("fancybox-button--pause");
40142
40143        self.isActive = true;
40144
40145        if (current.isComplete) {
40146          self.set(true);
40147        }
40148
40149        self.instance.trigger("onSlideShowChange", true);
40150      }
40151    },
40152
40153    stop: function () {
40154      var self = this,
40155        current = self.instance.current;
40156
40157      self.clear();
40158
40159      self.$button
40160        .attr("title", (current.opts.i18n[current.opts.lang] || current.opts.i18n.en).PLAY_START)
40161        .removeClass("fancybox-button--pause")
40162        .addClass("fancybox-button--play");
40163
40164      self.isActive = false;
40165
40166      self.instance.trigger("onSlideShowChange", false);
40167
40168      if (self.$progress) {
40169        self.$progress.removeAttr("style").hide();
40170      }
40171    },
40172
40173    toggle: function () {
40174      var self = this;
40175
40176      if (self.isActive) {
40177        self.stop();
40178      } else {
40179        self.start();
40180      }
40181    }
40182  });
40183
40184  $(document).on({
40185    "onInit.fb": function (e, instance) {
40186      if (instance && !instance.SlideShow) {
40187        instance.SlideShow = new SlideShow(instance);
40188      }
40189    },
40190
40191    "beforeShow.fb": function (e, instance, current, firstRun) {
40192      var SlideShow = instance && instance.SlideShow;
40193
40194      if (firstRun) {
40195        if (SlideShow && current.opts.slideShow.autoStart) {
40196          SlideShow.start();
40197        }
40198      } else if (SlideShow && SlideShow.isActive) {
40199        SlideShow.clear();
40200      }
40201    },
40202
40203    "afterShow.fb": function (e, instance, current) {
40204      var SlideShow = instance && instance.SlideShow;
40205
40206      if (SlideShow && SlideShow.isActive) {
40207        SlideShow.set();
40208      }
40209    },
40210
40211    "afterKeydown.fb": function (e, instance, current, keypress, keycode) {
40212      var SlideShow = instance && instance.SlideShow;
40213
40214      // "P" or Spacebar
40215      if (SlideShow && current.opts.slideShow && (keycode === 80 || keycode === 32) && !$(document.activeElement).is("button,a,input")) {
40216        keypress.preventDefault();
40217
40218        SlideShow.toggle();
40219      }
40220    },
40221
40222    "beforeClose.fb onDeactivate.fb": function (e, instance) {
40223      var SlideShow = instance && instance.SlideShow;
40224
40225      if (SlideShow) {
40226        SlideShow.stop();
40227      }
40228    }
40229  });
40230
40231  // Page Visibility API to pause slideshow when window is not active
40232  $(document).on("visibilitychange", function () {
40233    var instance = $.fancybox.getInstance(),
40234      SlideShow = instance && instance.SlideShow;
40235
40236    if (SlideShow && SlideShow.isActive) {
40237      if (document.hidden) {
40238        SlideShow.clear();
40239      } else {
40240        SlideShow.set();
40241      }
40242    }
40243  });
40244})(document, jQuery);
40245// ==========================================================================
40246//
40247// FullScreen
40248// Adds fullscreen functionality
40249//
40250// ==========================================================================
40251(function (document, $) {
40252  "use strict";
40253
40254  // Collection of methods supported by user browser
40255  var fn = (function () {
40256    var fnMap = [
40257      ["requestFullscreen", "exitFullscreen", "fullscreenElement", "fullscreenEnabled", "fullscreenchange", "fullscreenerror"],
40258      // new WebKit
40259      [
40260        "webkitRequestFullscreen",
40261        "webkitExitFullscreen",
40262        "webkitFullscreenElement",
40263        "webkitFullscreenEnabled",
40264        "webkitfullscreenchange",
40265        "webkitfullscreenerror"
40266      ],
40267      // old WebKit (Safari 5.1)
40268      [
40269        "webkitRequestFullScreen",
40270        "webkitCancelFullScreen",
40271        "webkitCurrentFullScreenElement",
40272        "webkitCancelFullScreen",
40273        "webkitfullscreenchange",
40274        "webkitfullscreenerror"
40275      ],
40276      [
40277        "mozRequestFullScreen",
40278        "mozCancelFullScreen",
40279        "mozFullScreenElement",
40280        "mozFullScreenEnabled",
40281        "mozfullscreenchange",
40282        "mozfullscreenerror"
40283      ],
40284      ["msRequestFullscreen", "msExitFullscreen", "msFullscreenElement", "msFullscreenEnabled", "MSFullscreenChange", "MSFullscreenError"]
40285    ];
40286
40287    var ret = {};
40288
40289    for (var i = 0; i < fnMap.length; i++) {
40290      var val = fnMap[i];
40291
40292      if (val && val[1] in document) {
40293        for (var j = 0; j < val.length; j++) {
40294          ret[fnMap[0][j]] = val[j];
40295        }
40296
40297        return ret;
40298      }
40299    }
40300
40301    return false;
40302  })();
40303
40304  if (fn) {
40305    var FullScreen = {
40306      request: function (elem) {
40307        elem = elem || document.documentElement;
40308
40309        elem[fn.requestFullscreen](elem.ALLOW_KEYBOARD_INPUT);
40310      },
40311      exit: function () {
40312        document[fn.exitFullscreen]();
40313      },
40314      toggle: function (elem) {
40315        elem = elem || document.documentElement;
40316
40317        if (this.isFullscreen()) {
40318          this.exit();
40319        } else {
40320          this.request(elem);
40321        }
40322      },
40323      isFullscreen: function () {
40324        return Boolean(document[fn.fullscreenElement]);
40325      },
40326      enabled: function () {
40327        return Boolean(document[fn.fullscreenEnabled]);
40328      }
40329    };
40330
40331    $.extend(true, $.fancybox.defaults, {
40332      btnTpl: {
40333        fullScreen: '<button data-fancybox-fullscreen class="fancybox-button fancybox-button--fsenter" title="{{FULL_SCREEN}}">' +
40334          '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>' +
40335          '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 16h3v3h2v-5H5zm3-8H5v2h5V5H8zm6 11h2v-3h3v-2h-5zm2-11V5h-2v5h5V8z"/></svg>' +
40336          "</button>"
40337      },
40338      fullScreen: {
40339        autoStart: false
40340      }
40341    });
40342
40343    $(document).on(fn.fullscreenchange, function () {
40344      var isFullscreen = FullScreen.isFullscreen(),
40345        instance = $.fancybox.getInstance();
40346
40347      if (instance) {
40348        // If image is zooming, then force to stop and reposition properly
40349        if (instance.current && instance.current.type === "image" && instance.isAnimating) {
40350          instance.isAnimating = false;
40351
40352          instance.update(true, true, 0);
40353
40354          if (!instance.isComplete) {
40355            instance.complete();
40356          }
40357        }
40358
40359        instance.trigger("onFullscreenChange", isFullscreen);
40360
40361        instance.$refs.container.toggleClass("fancybox-is-fullscreen", isFullscreen);
40362
40363        instance.$refs.toolbar
40364          .find("[data-fancybox-fullscreen]")
40365          .toggleClass("fancybox-button--fsenter", !isFullscreen)
40366          .toggleClass("fancybox-button--fsexit", isFullscreen);
40367      }
40368    });
40369  }
40370
40371  $(document).on({
40372    "onInit.fb": function (e, instance) {
40373      var $container;
40374
40375      if (!fn) {
40376        instance.$refs.toolbar.find("[data-fancybox-fullscreen]").remove();
40377
40378        return;
40379      }
40380
40381      if (instance && instance.group[instance.currIndex].opts.fullScreen) {
40382        $container = instance.$refs.container;
40383
40384        $container.on("click.fb-fullscreen", "[data-fancybox-fullscreen]", function (e) {
40385          e.stopPropagation();
40386          e.preventDefault();
40387
40388          FullScreen.toggle();
40389        });
40390
40391        if (instance.opts.fullScreen && instance.opts.fullScreen.autoStart === true) {
40392          FullScreen.request();
40393        }
40394
40395        // Expose API
40396        instance.FullScreen = FullScreen;
40397      } else if (instance) {
40398        instance.$refs.toolbar.find("[data-fancybox-fullscreen]").hide();
40399      }
40400    },
40401
40402    "afterKeydown.fb": function (e, instance, current, keypress, keycode) {
40403      // "F"
40404      if (instance && instance.FullScreen && keycode === 70) {
40405        keypress.preventDefault();
40406
40407        instance.FullScreen.toggle();
40408      }
40409    },
40410
40411    "beforeClose.fb": function (e, instance) {
40412      if (instance && instance.FullScreen && instance.$refs.container.hasClass("fancybox-is-fullscreen")) {
40413        FullScreen.exit();
40414      }
40415    }
40416  });
40417})(document, jQuery);
40418// ==========================================================================
40419//
40420// Thumbs
40421// Displays thumbnails in a grid
40422//
40423// ==========================================================================
40424(function (document, $) {
40425  "use strict";
40426
40427  var CLASS = "fancybox-thumbs",
40428    CLASS_ACTIVE = CLASS + "-active";
40429
40430  // Make sure there are default values
40431  $.fancybox.defaults = $.extend(
40432    true, {
40433      btnTpl: {
40434        thumbs: '<button data-fancybox-thumbs class="fancybox-button fancybox-button--thumbs" title="{{THUMBS}}">' +
40435          '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14.59 14.59h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76H5.65V5.65z"/></svg>' +
40436          "</button>"
40437      },
40438      thumbs: {
40439        autoStart: false, // Display thumbnails on opening
40440        hideOnClose: true, // Hide thumbnail grid when closing animation starts
40441        parentEl: ".fancybox-container", // Container is injected into this element
40442        axis: "y" // Vertical (y) or horizontal (x) scrolling
40443      }
40444    },
40445    $.fancybox.defaults
40446  );
40447
40448  var FancyThumbs = function (instance) {
40449    this.init(instance);
40450  };
40451
40452  $.extend(FancyThumbs.prototype, {
40453    $button: null,
40454    $grid: null,
40455    $list: null,
40456    isVisible: false,
40457    isActive: false,
40458
40459    init: function (instance) {
40460      var self = this,
40461        group = instance.group,
40462        enabled = 0;
40463
40464      self.instance = instance;
40465      self.opts = group[instance.currIndex].opts.thumbs;
40466
40467      instance.Thumbs = self;
40468
40469      self.$button = instance.$refs.toolbar.find("[data-fancybox-thumbs]");
40470
40471      // Enable thumbs if at least two group items have thumbnails
40472      for (var i = 0, len = group.length; i < len; i++) {
40473        if (group[i].thumb) {
40474          enabled++;
40475        }
40476
40477        if (enabled > 1) {
40478          break;
40479        }
40480      }
40481
40482      if (enabled > 1 && !!self.opts) {
40483        self.$button.removeAttr("style").on("click", function () {
40484          self.toggle();
40485        });
40486
40487        self.isActive = true;
40488      } else {
40489        self.$button.hide();
40490      }
40491    },
40492
40493    create: function () {
40494      var self = this,
40495        instance = self.instance,
40496        parentEl = self.opts.parentEl,
40497        list = [],
40498        src;
40499
40500      if (!self.$grid) {
40501        // Create main element
40502        self.$grid = $('<div class="' + CLASS + " " + CLASS + "-" + self.opts.axis + '"></div>').appendTo(
40503          instance.$refs.container
40504          .find(parentEl)
40505          .addBack()
40506          .filter(parentEl)
40507        );
40508
40509        // Add "click" event that performs gallery navigation
40510        self.$grid.on("click", "a", function () {
40511          instance.jumpTo($(this).attr("data-index"));
40512        });
40513      }
40514
40515      // Build the list
40516      if (!self.$list) {
40517        self.$list = $('<div class="' + CLASS + '__list">').appendTo(self.$grid);
40518      }
40519
40520      $.each(instance.group, function (i, item) {
40521        src = item.thumb;
40522
40523        if (!src && item.type === "image") {
40524          src = item.src;
40525        }
40526
40527        list.push(
40528          '<a href="javascript:;" tabindex="0" data-index="' +
40529          i +
40530          '"' +
40531          (src && src.length ? ' style="background-image:url(' + src + ')"' : 'class="fancybox-thumbs-missing"') +
40532          "></a>"
40533        );
40534      });
40535
40536      self.$list[0].innerHTML = list.join("");
40537
40538      if (self.opts.axis === "x") {
40539        // Set fixed width for list element to enable horizontal scrolling
40540        self.$list.width(
40541          parseInt(self.$grid.css("padding-right"), 10) +
40542          instance.group.length *
40543          self.$list
40544          .children()
40545          .eq(0)
40546          .outerWidth(true)
40547        );
40548      }
40549    },
40550
40551    focus: function (duration) {
40552      var self = this,
40553        $list = self.$list,
40554        $grid = self.$grid,
40555        thumb,
40556        thumbPos;
40557
40558      if (!self.instance.current) {
40559        return;
40560      }
40561
40562      thumb = $list
40563        .children()
40564        .removeClass(CLASS_ACTIVE)
40565        .filter('[data-index="' + self.instance.current.index + '"]')
40566        .addClass(CLASS_ACTIVE);
40567
40568      thumbPos = thumb.position();
40569
40570      // Check if need to scroll to make current thumb visible
40571      if (self.opts.axis === "y" && (thumbPos.top < 0 || thumbPos.top > $list.height() - thumb.outerHeight())) {
40572        $list.stop().animate({
40573            scrollTop: $list.scrollTop() + thumbPos.top
40574          },
40575          duration
40576        );
40577      } else if (
40578        self.opts.axis === "x" &&
40579        (thumbPos.left < $grid.scrollLeft() || thumbPos.left > $grid.scrollLeft() + ($grid.width() - thumb.outerWidth()))
40580      ) {
40581        $list
40582          .parent()
40583          .stop()
40584          .animate({
40585              scrollLeft: thumbPos.left
40586            },
40587            duration
40588          );
40589      }
40590    },
40591
40592    update: function () {
40593      var that = this;
40594      that.instance.$refs.container.toggleClass("fancybox-show-thumbs", this.isVisible);
40595
40596      if (that.isVisible) {
40597        if (!that.$grid) {
40598          that.create();
40599        }
40600
40601        that.instance.trigger("onThumbsShow");
40602
40603        that.focus(0);
40604      } else if (that.$grid) {
40605        that.instance.trigger("onThumbsHide");
40606      }
40607
40608      // Update content position
40609      that.instance.update();
40610    },
40611
40612    hide: function () {
40613      this.isVisible = false;
40614      this.update();
40615    },
40616
40617    show: function () {
40618      this.isVisible = true;
40619      this.update();
40620    },
40621
40622    toggle: function () {
40623      this.isVisible = !this.isVisible;
40624      this.update();
40625    }
40626  });
40627
40628  $(document).on({
40629    "onInit.fb": function (e, instance) {
40630      var Thumbs;
40631
40632      if (instance && !instance.Thumbs) {
40633        Thumbs = new FancyThumbs(instance);
40634
40635        if (Thumbs.isActive && Thumbs.opts.autoStart === true) {
40636          Thumbs.show();
40637        }
40638      }
40639    },
40640
40641    "beforeShow.fb": function (e, instance, item, firstRun) {
40642      var Thumbs = instance && instance.Thumbs;
40643
40644      if (Thumbs && Thumbs.isVisible) {
40645        Thumbs.focus(firstRun ? 0 : 250);
40646      }
40647    },
40648
40649    "afterKeydown.fb": function (e, instance, current, keypress, keycode) {
40650      var Thumbs = instance && instance.Thumbs;
40651
40652      // "G"
40653      if (Thumbs && Thumbs.isActive && keycode === 71) {
40654        keypress.preventDefault();
40655
40656        Thumbs.toggle();
40657      }
40658    },
40659
40660    "beforeClose.fb": function (e, instance) {
40661      var Thumbs = instance && instance.Thumbs;
40662
40663      if (Thumbs && Thumbs.isVisible && Thumbs.opts.hideOnClose !== false) {
40664        Thumbs.$grid.hide();
40665      }
40666    }
40667  });
40668})(document, jQuery);
40669//// ==========================================================================
40670//
40671// Share
40672// Displays simple form for sharing current url
40673//
40674// ==========================================================================
40675(function (document, $) {
40676  "use strict";
40677
40678  $.extend(true, $.fancybox.defaults, {
40679    btnTpl: {
40680      share: '<button data-fancybox-share class="fancybox-button fancybox-button--share" title="{{SHARE}}">' +
40681        '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2.55 19c1.4-8.4 9.1-9.8 11.9-9.8V5l7 7-7 6.3v-3.5c-2.8 0-10.5 2.1-11.9 4.2z"/></svg>' +
40682        "</button>"
40683    },
40684    share: {
40685      url: function (instance, item) {
40686        return (
40687          (!instance.currentHash && !(item.type === "inline" || item.type === "html") ? item.origSrc || item.src : false) || window.location
40688        );
40689      },
40690      tpl: '<div class="fancybox-share">' +
40691        "<h1>{{SHARE}}</h1>" +
40692        "<p>" +
40693        '<a class="fancybox-share__button fancybox-share__button--fb" href="https://www.facebook.com/sharer/sharer.php?u={{url}}">' +
40694        '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m287 456v-299c0-21 6-35 35-35h38v-63c-7-1-29-3-55-3-54 0-91 33-91 94v306m143-254h-205v72h196" /></svg>' +
40695        "<span>Facebook</span>" +
40696        "</a>" +
40697        '<a class="fancybox-share__button fancybox-share__button--tw" href="https://twitter.com/intent/tweet?url={{url}}&text={{descr}}">' +
40698        '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m456 133c-14 7-31 11-47 13 17-10 30-27 37-46-15 10-34 16-52 20-61-62-157-7-141 75-68-3-129-35-169-85-22 37-11 86 26 109-13 0-26-4-37-9 0 39 28 72 65 80-12 3-25 4-37 2 10 33 41 57 77 57-42 30-77 38-122 34 170 111 378-32 359-208 16-11 30-25 41-42z" /></svg>' +
40699        "<span>Twitter</span>" +
40700        "</a>" +
40701        '<a class="fancybox-share__button fancybox-share__button--pt" href="https://www.pinterest.com/pin/create/button/?url={{url}}&description={{descr}}&media={{media}}">' +
40702        '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m265 56c-109 0-164 78-164 144 0 39 15 74 47 87 5 2 10 0 12-5l4-19c2-6 1-8-3-13-9-11-15-25-15-45 0-58 43-110 113-110 62 0 96 38 96 88 0 67-30 122-73 122-24 0-42-19-36-44 6-29 20-60 20-81 0-19-10-35-31-35-25 0-44 26-44 60 0 21 7 36 7 36l-30 125c-8 37-1 83 0 87 0 3 4 4 5 2 2-3 32-39 42-75l16-64c8 16 31 29 56 29 74 0 124-67 124-157 0-69-58-132-146-132z" fill="#fff"/></svg>' +
40703        "<span>Pinterest</span>" +
40704        "</a>" +
40705        "</p>" +
40706        '<p><input class="fancybox-share__input" type="text" value="{{url_raw}}" onclick="select()" /></p>' +
40707        "</div>"
40708    }
40709  });
40710
40711  function escapeHtml(string) {
40712    var entityMap = {
40713      "&": "&amp;",
40714      "<": "&lt;",
40715      ">": "&gt;",
40716      '"': "&quot;",
40717      "'": "&#39;",
40718      "/": "&#x2F;",
40719      "`": "&#x60;",
40720      "=": "&#x3D;"
40721    };
40722
40723    return String(string).replace(/[&<>"'`=\/]/g, function (s) {
40724      return entityMap[s];
40725    });
40726  }
40727
40728  $(document).on("click", "[data-fancybox-share]", function () {
40729    var instance = $.fancybox.getInstance(),
40730      current = instance.current || null,
40731      url,
40732      tpl;
40733
40734    if (!current) {
40735      return;
40736    }
40737
40738    if ($.type(current.opts.share.url) === "function") {
40739      url = current.opts.share.url.apply(current, [instance, current]);
40740    }
40741
40742    tpl = current.opts.share.tpl
40743      .replace(/\{\{media\}\}/g, current.type === "image" ? encodeURIComponent(current.src) : "")
40744      .replace(/\{\{url\}\}/g, encodeURIComponent(url))
40745      .replace(/\{\{url_raw\}\}/g, escapeHtml(url))
40746      .replace(/\{\{descr\}\}/g, instance.$caption ? encodeURIComponent(instance.$caption.text()) : "");
40747
40748    $.fancybox.open({
40749      src: instance.translate(instance, tpl),
40750      type: "html",
40751      opts: {
40752        touch: false,
40753        animationEffect: false,
40754        afterLoad: function (shareInstance, shareCurrent) {
40755          // Close self if parent instance is closing
40756          instance.$refs.container.one("beforeClose.fb", function () {
40757            shareInstance.close(null, 0);
40758          });
40759
40760          // Opening links in a popup window
40761          shareCurrent.$content.find(".fancybox-share__button").click(function () {
40762            window.open(this.href, "Share", "width=550, height=450");
40763            return false;
40764          });
40765        },
40766        mobile: {
40767          autoFocus: false
40768        }
40769      }
40770    });
40771  });
40772})(document, jQuery);
40773// ==========================================================================
40774//
40775// Hash
40776// Enables linking to each modal
40777//
40778// ==========================================================================
40779(function (window, document, $) {
40780  "use strict";
40781
40782  // Simple $.escapeSelector polyfill (for jQuery prior v3)
40783  if (!$.escapeSelector) {
40784    $.escapeSelector = function (sel) {
40785      var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
40786      var fcssescape = function (ch, asCodePoint) {
40787        if (asCodePoint) {
40788          // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
40789          if (ch === "\0") {
40790            return "\uFFFD";
40791          }
40792
40793          // Control characters and (dependent upon position) numbers get escaped as code points
40794          return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";
40795        }
40796
40797        // Other potentially-special ASCII characters get backslash-escaped
40798        return "\\" + ch;
40799      };
40800
40801      return (sel + "").replace(rcssescape, fcssescape);
40802    };
40803  }
40804
40805  // Get info about gallery name and current index from url
40806  function parseUrl() {
40807    var hash = window.location.hash.substr(1),
40808      rez = hash.split("-"),
40809      index = rez.length > 1 && /^\+?\d+$/.test(rez[rez.length - 1]) ? parseInt(rez.pop(-1), 10) || 1 : 1,
40810      gallery = rez.join("-");
40811
40812    return {
40813      hash: hash,
40814      /* Index is starting from 1 */
40815      index: index < 1 ? 1 : index,
40816      gallery: gallery
40817    };
40818  }
40819
40820  // Trigger click evnt on links to open new fancyBox instance
40821  function triggerFromUrl(url) {
40822    if (url.gallery !== "") {
40823      // If we can find element matching 'data-fancybox' atribute,
40824      // then triggering click event should start fancyBox
40825      $("[data-fancybox='" + $.escapeSelector(url.gallery) + "']")
40826        .eq(url.index - 1)
40827        .focus()
40828        .trigger("click.fb-start");
40829    }
40830  }
40831
40832  // Get gallery name from current instance
40833  function getGalleryID(instance) {
40834    var opts, ret;
40835
40836    if (!instance) {
40837      return false;
40838    }
40839
40840    opts = instance.current ? instance.current.opts : instance.opts;
40841    ret = opts.hash || (opts.$orig ? opts.$orig.data("fancybox") || opts.$orig.data("fancybox-trigger") : "");
40842
40843    return ret === "" ? false : ret;
40844  }
40845
40846  // Start when DOM becomes ready
40847  $(function () {
40848    // Check if user has disabled this module
40849    if ($.fancybox.defaults.hash === false) {
40850      return;
40851    }
40852
40853    // Update hash when opening/closing fancyBox
40854    $(document).on({
40855      "onInit.fb": function (e, instance) {
40856        var url, gallery;
40857
40858        if (instance.group[instance.currIndex].opts.hash === false) {
40859          return;
40860        }
40861
40862        url = parseUrl();
40863        gallery = getGalleryID(instance);
40864
40865        // Make sure gallery start index matches index from hash
40866        if (gallery && url.gallery && gallery == url.gallery) {
40867          instance.currIndex = url.index - 1;
40868        }
40869      },
40870
40871      "beforeShow.fb": function (e, instance, current, firstRun) {
40872        var gallery;
40873
40874        if (!current || current.opts.hash === false) {
40875          return;
40876        }
40877
40878        // Check if need to update window hash
40879        gallery = getGalleryID(instance);
40880
40881        if (!gallery) {
40882          return;
40883        }
40884
40885        // Variable containing last hash value set by fancyBox
40886        // It will be used to determine if fancyBox needs to close after hash change is detected
40887        instance.currentHash = gallery + (instance.group.length > 1 ? "-" + (current.index + 1) : "");
40888
40889        // If current hash is the same (this instance most likely is opened by hashchange), then do nothing
40890        if (window.location.hash === "#" + instance.currentHash) {
40891          return;
40892        }
40893
40894        if (firstRun && !instance.origHash) {
40895          instance.origHash = window.location.hash;
40896        }
40897
40898        if (instance.hashTimer) {
40899          clearTimeout(instance.hashTimer);
40900        }
40901
40902        // Update hash
40903        instance.hashTimer = setTimeout(function () {
40904          if ("replaceState" in window.history) {
40905            window.history[firstRun ? "pushState" : "replaceState"]({},
40906              document.title,
40907              window.location.pathname + window.location.search + "#" + instance.currentHash
40908            );
40909
40910            if (firstRun) {
40911              instance.hasCreatedHistory = true;
40912            }
40913          } else {
40914            window.location.hash = instance.currentHash;
40915          }
40916
40917          instance.hashTimer = null;
40918        }, 300);
40919      },
40920
40921      "beforeClose.fb": function (e, instance, current) {
40922        if (!current || current.opts.hash === false) {
40923          return;
40924        }
40925
40926        clearTimeout(instance.hashTimer);
40927
40928        // Goto previous history entry
40929        if (instance.currentHash && instance.hasCreatedHistory) {
40930          window.history.back();
40931        } else if (instance.currentHash) {
40932          if ("replaceState" in window.history) {
40933            window.history.replaceState({}, document.title, window.location.pathname + window.location.search + (instance.origHash || ""));
40934          } else {
40935            window.location.hash = instance.origHash;
40936          }
40937        }
40938
40939        instance.currentHash = null;
40940      }
40941    });
40942
40943    // Check if need to start/close after url has changed
40944    $(window).on("hashchange.fb", function () {
40945      var url = parseUrl(),
40946        fb = null;
40947
40948      // Find last fancyBox instance that has "hash"
40949      $.each(
40950        $(".fancybox-container")
40951        .get()
40952        .reverse(),
40953        function (index, value) {
40954          var tmp = $(value).data("FancyBox");
40955
40956          if (tmp && tmp.currentHash) {
40957            fb = tmp;
40958            return false;
40959          }
40960        }
40961      );
40962
40963      if (fb) {
40964        // Now, compare hash values
40965        if (fb.currentHash !== url.gallery + "-" + url.index && !(url.index === 1 && fb.currentHash == url.gallery)) {
40966          fb.currentHash = null;
40967
40968          fb.close();
40969        }
40970      } else if (url.gallery !== "") {
40971        triggerFromUrl(url);
40972      }
40973    });
40974
40975    // Check current hash and trigger click event on matching element to start fancyBox, if needed
40976    setTimeout(function () {
40977      if (!$.fancybox.getInstance()) {
40978        triggerFromUrl(parseUrl());
40979      }
40980    }, 50);
40981  });
40982})(window, document, jQuery);
40983// ==========================================================================
40984//
40985// Wheel
40986// Basic mouse weheel support for gallery navigation
40987//
40988// ==========================================================================
40989(function (document, $) {
40990  "use strict";
40991
40992  var prevTime = new Date().getTime();
40993
40994  $(document).on({
40995    "onInit.fb": function (e, instance, current) {
40996      instance.$refs.stage.on("mousewheel DOMMouseScroll wheel MozMousePixelScroll", function (e) {
40997        var current = instance.current,
40998          currTime = new Date().getTime();
40999
41000        if (instance.group.length < 2 || current.opts.wheel === false || (current.opts.wheel === "auto" && current.type !== "image")) {
41001          return;
41002        }
41003
41004        e.preventDefault();
41005        e.stopPropagation();
41006
41007        if (current.$slide.hasClass("fancybox-animated")) {
41008          return;
41009        }
41010
41011        e = e.originalEvent || e;
41012
41013        if (currTime - prevTime < 250) {
41014          return;
41015        }
41016
41017        prevTime = currTime;
41018
41019        instance[(-e.deltaY || -e.deltaX || e.wheelDelta || -e.detail) < 0 ? "next" : "previous"]();
41020      });
41021    }
41022  });
41023})(document, jQuery);
41024/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2)))
41025
41026/***/ }),
41027/* 166 */
41028/***/ (function(module, __webpack_exports__, __webpack_require__) {
41029
41030"use strict";
41031/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return $; });
41032/* unused harmony export add */
41033/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return addClass; });
41034/* unused harmony export animate */
41035/* unused harmony export animationEnd */
41036/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return append; });
41037/* unused harmony export appendTo */
41038/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return attr; });
41039/* unused harmony export blur */
41040/* unused harmony export change */
41041/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return children; });
41042/* unused harmony export click */
41043/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "f", function() { return closest; });
41044/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "g", function() { return css; });
41045/* unused harmony export data */
41046/* unused harmony export dataset */
41047/* unused harmony export detach */
41048/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "h", function() { return each; });
41049/* unused harmony export empty */
41050/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "i", function() { return eq; });
41051/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "j", function() { return filter; });
41052/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "k", function() { return find; });
41053/* unused harmony export focus */
41054/* unused harmony export focusin */
41055/* unused harmony export focusout */
41056/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "l", function() { return hasClass; });
41057/* unused harmony export height */
41058/* unused harmony export hide */
41059/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "m", function() { return html; });
41060/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "n", function() { return index; });
41061/* unused harmony export insertAfter */
41062/* unused harmony export insertBefore */
41063/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "o", function() { return is; });
41064/* unused harmony export keydown */
41065/* unused harmony export keypress */
41066/* unused harmony export keyup */
41067/* unused harmony export mousedown */
41068/* unused harmony export mouseenter */
41069/* unused harmony export mouseleave */
41070/* unused harmony export mousemove */
41071/* unused harmony export mouseout */
41072/* unused harmony export mouseover */
41073/* unused harmony export mouseup */
41074/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "p", function() { return next; });
41075/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "q", function() { return nextAll; });
41076/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "r", function() { return off; });
41077/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "s", function() { return offset; });
41078/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "t", function() { return on; });
41079/* unused harmony export once */
41080/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "u", function() { return outerHeight; });
41081/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "v", function() { return outerWidth; });
41082/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "w", function() { return parent; });
41083/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "x", function() { return parents; });
41084/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "y", function() { return prepend; });
41085/* unused harmony export prependTo */
41086/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "z", function() { return prev; });
41087/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "A", function() { return prevAll; });
41088/* unused harmony export prop */
41089/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "B", function() { return remove; });
41090/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "C", function() { return removeAttr; });
41091/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "D", function() { return removeClass; });
41092/* unused harmony export removeData */
41093/* unused harmony export resize */
41094/* unused harmony export scroll */
41095/* unused harmony export scrollLeft */
41096/* unused harmony export scrollTo */
41097/* unused harmony export scrollTop */
41098/* unused harmony export show */
41099/* unused harmony export siblings */
41100/* unused harmony export stop */
41101/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "E", function() { return styles; });
41102/* unused harmony export submit */
41103/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "F", function() { return text; });
41104/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "G", function() { return toggleClass; });
41105/* unused harmony export touchend */
41106/* unused harmony export touchmove */
41107/* unused harmony export touchstart */
41108/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "H", function() { return transform; });
41109/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "I", function() { return transition; });
41110/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "J", function() { return transitionEnd; });
41111/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "K", function() { return trigger; });
41112/* unused harmony export val */
41113/* unused harmony export value */
41114/* unused harmony export width */
41115/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
41116/**
41117 * Dom7 3.0.0
41118 * Minimalistic JavaScript library for DOM manipulation, with a jQuery-compatible API
41119 * https://framework7.io/docs/dom7.html
41120 *
41121 * Copyright 2020, Vladimir Kharlampidi
41122 *
41123 * Licensed under MIT
41124 *
41125 * Released on: November 9, 2020
41126 */
41127
41128
41129function _inheritsLoose(subClass, superClass) {
41130  subClass.prototype = Object.create(superClass.prototype);
41131  subClass.prototype.constructor = subClass;
41132  subClass.__proto__ = superClass;
41133}
41134
41135function _getPrototypeOf(o) {
41136  _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
vendor: 39,569 bytes, lines 41137-42775
41137    return o.__proto__ || Object.getPrototypeOf(o);
41138  };
41139  return _getPrototypeOf(o);
41140}
41141
41142function _setPrototypeOf(o, p) {
41143  _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
41144    o.__proto__ = p;
41145    return o;
41146  };
41147
41148  return _setPrototypeOf(o, p);
41149}
41150
41151function _isNativeReflectConstruct() {
41152  if (typeof Reflect === "undefined" || !Reflect.construct) return false;
41153  if (Reflect.construct.sham) return false;
41154  if (typeof Proxy === "function") return true;
41155
41156  try {
41157    Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
41158    return true;
41159  } catch (e) {
41160    return false;
41161  }
41162}
41163
41164function _construct(Parent, args, Class) {
41165  if (_isNativeReflectConstruct()) {
41166    _construct = Reflect.construct;
41167  } else {
41168    _construct = function _construct(Parent, args, Class) {
41169      var a = [null];
41170      a.push.apply(a, args);
41171      var Constructor = Function.bind.apply(Parent, a);
41172      var instance = new Constructor();
41173      if (Class) _setPrototypeOf(instance, Class.prototype);
41174      return instance;
41175    };
41176  }
41177
41178  return _construct.apply(null, arguments);
41179}
41180
41181function _isNativeFunction(fn) {
41182  return Function.toString.call(fn).indexOf("[native code]") !== -1;
41183}
41184
41185function _wrapNativeSuper(Class) {
41186  var _cache = typeof Map === "function" ? new Map() : undefined;
41187
41188  _wrapNativeSuper = function _wrapNativeSuper(Class) {
41189    if (Class === null || !_isNativeFunction(Class)) return Class;
41190
41191    if (typeof Class !== "function") {
41192      throw new TypeError("Super expression must either be null or a function");
41193    }
41194
41195    if (typeof _cache !== "undefined") {
41196      if (_cache.has(Class)) return _cache.get(Class);
41197
41198      _cache.set(Class, Wrapper);
41199    }
41200
41201    function Wrapper() {
41202      return _construct(Class, arguments, _getPrototypeOf(this).constructor);
41203    }
41204
41205    Wrapper.prototype = Object.create(Class.prototype, {
41206      constructor: {
41207        value: Wrapper,
41208        enumerable: false,
41209        writable: true,
41210        configurable: true
41211      }
41212    });
41213    return _setPrototypeOf(Wrapper, Class);
41214  };
41215
41216  return _wrapNativeSuper(Class);
41217}
41218
41219function _assertThisInitialized(self) {
41220  if (self === void 0) {
41221    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
41222  }
41223
41224  return self;
41225}
41226
41227/* eslint-disable no-proto */
41228function makeReactive(obj) {
41229  var proto = obj.__proto__;
41230  Object.defineProperty(obj, '__proto__', {
41231    get: function get() {
41232      return proto;
41233    },
41234    set: function set(value) {
41235      proto.__proto__ = value;
41236    }
41237  });
41238}
41239
41240var Dom7 = /*#__PURE__*/function (_Array) {
41241  _inheritsLoose(Dom7, _Array);
41242
41243  function Dom7(items) {
41244    var _this;
41245
41246    _this = _Array.call.apply(_Array, [this].concat(items)) || this;
41247    makeReactive(_assertThisInitialized(_this));
41248    return _this;
41249  }
41250
41251  return Dom7;
41252}( /*#__PURE__*/_wrapNativeSuper(Array));
41253
41254function arrayFlat(arr) {
41255  if (arr === void 0) {
41256    arr = [];
41257  }
41258
41259  var res = [];
41260  arr.forEach(function (el) {
41261    if (Array.isArray(el)) {
41262      res.push.apply(res, arrayFlat(el));
41263    } else {
41264      res.push(el);
41265    }
41266  });
41267  return res;
41268}
41269function arrayFilter(arr, callback) {
41270  return Array.prototype.filter.call(arr, callback);
41271}
41272function arrayUnique(arr) {
41273  var uniqueArray = [];
41274
41275  for (var i = 0; i < arr.length; i += 1) {
41276    if (uniqueArray.indexOf(arr[i]) === -1) uniqueArray.push(arr[i]);
41277  }
41278
41279  return uniqueArray;
41280}
41281function toCamelCase(string) {
41282  return string.toLowerCase().replace(/-(.)/g, function (match, group) {
41283    return group.toUpperCase();
41284  });
41285}
41286
41287function qsa(selector, context) {
41288  if (typeof selector !== 'string') {
41289    return [selector];
41290  }
41291
41292  var a = [];
41293  var res = context.querySelectorAll(selector);
41294
41295  for (var i = 0; i < res.length; i += 1) {
41296    a.push(res[i]);
41297  }
41298
41299  return a;
41300}
41301
41302function $(selector, context) {
41303  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
41304  var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
41305  var arr = [];
41306
41307  if (!context && selector instanceof Dom7) {
41308    return selector;
41309  }
41310
41311  if (!selector) {
41312    return new Dom7(arr);
41313  }
41314
41315  if (typeof selector === 'string') {
41316    var html = selector.trim();
41317
41318    if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {
41319      var toCreate = 'div';
41320      if (html.indexOf('<li') === 0) toCreate = 'ul';
41321      if (html.indexOf('<tr') === 0) toCreate = 'tbody';
41322      if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';
41323      if (html.indexOf('<tbody') === 0) toCreate = 'table';
41324      if (html.indexOf('<option') === 0) toCreate = 'select';
41325      var tempParent = document.createElement(toCreate);
41326      tempParent.innerHTML = html;
41327
41328      for (var i = 0; i < tempParent.childNodes.length; i += 1) {
41329        arr.push(tempParent.childNodes[i]);
41330      }
41331    } else {
41332      arr = qsa(selector.trim(), context || document);
41333    } // arr = qsa(selector, document);
41334
41335  } else if (selector.nodeType || selector === window || selector === document) {
41336    arr.push(selector);
41337  } else if (Array.isArray(selector)) {
41338    if (selector instanceof Dom7) return selector;
41339    arr = selector;
41340  }
41341
41342  return new Dom7(arrayUnique(arr));
41343}
41344
41345$.fn = Dom7.prototype;
41346
41347function addClass() {
41348  for (var _len = arguments.length, classes = new Array(_len), _key = 0; _key < _len; _key++) {
41349    classes[_key] = arguments[_key];
41350  }
41351
41352  var classNames = arrayFlat(classes.map(function (c) {
41353    return c.split(' ');
41354  }));
41355  this.forEach(function (el) {
41356    var _el$classList;
41357
41358    (_el$classList = el.classList).add.apply(_el$classList, classNames);
41359  });
41360  return this;
41361}
41362
41363function removeClass() {
41364  for (var _len2 = arguments.length, classes = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
41365    classes[_key2] = arguments[_key2];
41366  }
41367
41368  var classNames = arrayFlat(classes.map(function (c) {
41369    return c.split(' ');
41370  }));
41371  this.forEach(function (el) {
41372    var _el$classList2;
41373
41374    (_el$classList2 = el.classList).remove.apply(_el$classList2, classNames);
41375  });
41376  return this;
41377}
41378
41379function toggleClass() {
41380  for (var _len3 = arguments.length, classes = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
41381    classes[_key3] = arguments[_key3];
41382  }
41383
41384  var classNames = arrayFlat(classes.map(function (c) {
41385    return c.split(' ');
41386  }));
41387  this.forEach(function (el) {
41388    classNames.forEach(function (className) {
41389      el.classList.toggle(className);
41390    });
41391  });
41392}
41393
41394function hasClass() {
41395  for (var _len4 = arguments.length, classes = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
41396    classes[_key4] = arguments[_key4];
41397  }
41398
41399  var classNames = arrayFlat(classes.map(function (c) {
41400    return c.split(' ');
41401  }));
41402  return arrayFilter(this, function (el) {
41403    return classNames.filter(function (className) {
41404      return el.classList.contains(className);
41405    }).length > 0;
41406  }).length > 0;
41407}
41408
41409function attr(attrs, value) {
41410  if (arguments.length === 1 && typeof attrs === 'string') {
41411    // Get attr
41412    if (this[0]) return this[0].getAttribute(attrs);
41413    return undefined;
41414  } // Set attrs
41415
41416
41417  for (var i = 0; i < this.length; i += 1) {
41418    if (arguments.length === 2) {
41419      // String
41420      this[i].setAttribute(attrs, value);
41421    } else {
41422      // Object
41423      for (var attrName in attrs) {
41424        this[i][attrName] = attrs[attrName];
41425        this[i].setAttribute(attrName, attrs[attrName]);
41426      }
41427    }
41428  }
41429
41430  return this;
41431}
41432
41433function removeAttr(attr) {
41434  for (var i = 0; i < this.length; i += 1) {
41435    this[i].removeAttribute(attr);
41436  }
41437
41438  return this;
41439}
41440
41441function prop(props, value) {
41442  if (arguments.length === 1 && typeof props === 'string') {
41443    // Get prop
41444    if (this[0]) return this[0][props];
41445  } else {
41446    // Set props
41447    for (var i = 0; i < this.length; i += 1) {
41448      if (arguments.length === 2) {
41449        // String
41450        this[i][props] = value;
41451      } else {
41452        // Object
41453        for (var propName in props) {
41454          this[i][propName] = props[propName];
41455        }
41456      }
41457    }
41458
41459    return this;
41460  }
41461
41462  return this;
41463}
41464
41465function data(key, value) {
41466  var el;
41467
41468  if (typeof value === 'undefined') {
41469    el = this[0];
41470    if (!el) return undefined; // Get value
41471
41472    if (el.dom7ElementDataStorage && key in el.dom7ElementDataStorage) {
41473      return el.dom7ElementDataStorage[key];
41474    }
41475
41476    var dataKey = el.getAttribute("data-" + key);
41477
41478    if (dataKey) {
41479      return dataKey;
41480    }
41481
41482    return undefined;
41483  } // Set value
41484
41485
41486  for (var i = 0; i < this.length; i += 1) {
41487    el = this[i];
41488    if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};
41489    el.dom7ElementDataStorage[key] = value;
41490  }
41491
41492  return this;
41493}
41494
41495function removeData(key) {
41496  for (var i = 0; i < this.length; i += 1) {
41497    var el = this[i];
41498
41499    if (el.dom7ElementDataStorage && el.dom7ElementDataStorage[key]) {
41500      el.dom7ElementDataStorage[key] = null;
41501      delete el.dom7ElementDataStorage[key];
41502    }
41503  }
41504}
41505
41506function dataset() {
41507  var el = this[0];
41508  if (!el) return undefined;
41509  var dataset = {}; // eslint-disable-line
41510
41511  if (el.dataset) {
41512    for (var dataKey in el.dataset) {
41513      dataset[dataKey] = el.dataset[dataKey];
41514    }
41515  } else {
41516    for (var i = 0; i < el.attributes.length; i += 1) {
41517      var _attr = el.attributes[i];
41518
41519      if (_attr.name.indexOf('data-') >= 0) {
41520        dataset[toCamelCase(_attr.name.split('data-')[1])] = _attr.value;
41521      }
41522    }
41523  }
41524
41525  for (var key in dataset) {
41526    if (dataset[key] === 'false') dataset[key] = false;else if (dataset[key] === 'true') dataset[key] = true;else if (parseFloat(dataset[key]) === dataset[key] * 1) dataset[key] *= 1;
41527  }
41528
41529  return dataset;
41530}
41531
41532function val(value) {
41533  if (typeof value === 'undefined') {
41534    // get value
41535    var el = this[0];
41536    if (!el) return undefined;
41537
41538    if (el.multiple && el.nodeName.toLowerCase() === 'select') {
41539      var values = [];
41540
41541      for (var i = 0; i < el.selectedOptions.length; i += 1) {
41542        values.push(el.selectedOptions[i].value);
41543      }
41544
41545      return values;
41546    }
41547
41548    return el.value;
41549  } // set value
41550
41551
41552  for (var _i = 0; _i < this.length; _i += 1) {
41553    var _el = this[_i];
41554
41555    if (Array.isArray(value) && _el.multiple && _el.nodeName.toLowerCase() === 'select') {
41556      for (var j = 0; j < _el.options.length; j += 1) {
41557        _el.options[j].selected = value.indexOf(_el.options[j].value) >= 0;
41558      }
41559    } else {
41560      _el.value = value;
41561    }
41562  }
41563
41564  return this;
41565}
41566
41567function value(value) {
41568  return this.val(value);
41569}
41570
41571function transform(transform) {
41572  for (var i = 0; i < this.length; i += 1) {
41573    this[i].style.transform = transform;
41574  }
41575
41576  return this;
41577}
41578
41579function transition(duration) {
41580  for (var i = 0; i < this.length; i += 1) {
41581    this[i].style.transitionDuration = typeof duration !== 'string' ? duration + "ms" : duration;
41582  }
41583
41584  return this;
41585}
41586
41587function on() {
41588  for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
41589    args[_key5] = arguments[_key5];
41590  }
41591
41592  var eventType = args[0],
41593      targetSelector = args[1],
41594      listener = args[2],
41595      capture = args[3];
41596
41597  if (typeof args[1] === 'function') {
41598    eventType = args[0];
41599    listener = args[1];
41600    capture = args[2];
41601    targetSelector = undefined;
41602  }
41603
41604  if (!capture) capture = false;
41605
41606  function handleLiveEvent(e) {
41607    var target = e.target;
41608    if (!target) return;
41609    var eventData = e.target.dom7EventData || [];
41610
41611    if (eventData.indexOf(e) < 0) {
41612      eventData.unshift(e);
41613    }
41614
41615    if ($(target).is(targetSelector)) listener.apply(target, eventData);else {
41616      var _parents = $(target).parents(); // eslint-disable-line
41617
41618
41619      for (var k = 0; k < _parents.length; k += 1) {
41620        if ($(_parents[k]).is(targetSelector)) listener.apply(_parents[k], eventData);
41621      }
41622    }
41623  }
41624
41625  function handleEvent(e) {
41626    var eventData = e && e.target ? e.target.dom7EventData || [] : [];
41627
41628    if (eventData.indexOf(e) < 0) {
41629      eventData.unshift(e);
41630    }
41631
41632    listener.apply(this, eventData);
41633  }
41634
41635  var events = eventType.split(' ');
41636  var j;
41637
41638  for (var i = 0; i < this.length; i += 1) {
41639    var el = this[i];
41640
41641    if (!targetSelector) {
41642      for (j = 0; j < events.length; j += 1) {
41643        var event = events[j];
41644        if (!el.dom7Listeners) el.dom7Listeners = {};
41645        if (!el.dom7Listeners[event]) el.dom7Listeners[event] = [];
41646        el.dom7Listeners[event].push({
41647          listener: listener,
41648          proxyListener: handleEvent
41649        });
41650        el.addEventListener(event, handleEvent, capture);
41651      }
41652    } else {
41653      // Live events
41654      for (j = 0; j < events.length; j += 1) {
41655        var _event = events[j];
41656        if (!el.dom7LiveListeners) el.dom7LiveListeners = {};
41657        if (!el.dom7LiveListeners[_event]) el.dom7LiveListeners[_event] = [];
41658
41659        el.dom7LiveListeners[_event].push({
41660          listener: listener,
41661          proxyListener: handleLiveEvent
41662        });
41663
41664        el.addEventListener(_event, handleLiveEvent, capture);
41665      }
41666    }
41667  }
41668
41669  return this;
41670}
41671
41672function off() {
41673  for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
41674    args[_key6] = arguments[_key6];
41675  }
41676
41677  var eventType = args[0],
41678      targetSelector = args[1],
41679      listener = args[2],
41680      capture = args[3];
41681
41682  if (typeof args[1] === 'function') {
41683    eventType = args[0];
41684    listener = args[1];
41685    capture = args[2];
41686    targetSelector = undefined;
41687  }
41688
41689  if (!capture) capture = false;
41690  var events = eventType.split(' ');
41691
41692  for (var i = 0; i < events.length; i += 1) {
41693    var event = events[i];
41694
41695    for (var j = 0; j < this.length; j += 1) {
41696      var el = this[j];
41697      var handlers = void 0;
41698
41699      if (!targetSelector && el.dom7Listeners) {
41700        handlers = el.dom7Listeners[event];
41701      } else if (targetSelector && el.dom7LiveListeners) {
41702        handlers = el.dom7LiveListeners[event];
41703      }
41704
41705      if (handlers && handlers.length) {
41706        for (var k = handlers.length - 1; k >= 0; k -= 1) {
41707          var handler = handlers[k];
41708
41709          if (listener && handler.listener === listener) {
41710            el.removeEventListener(event, handler.proxyListener, capture);
41711            handlers.splice(k, 1);
41712          } else if (listener && handler.listener && handler.listener.dom7proxy && handler.listener.dom7proxy === listener) {
41713            el.removeEventListener(event, handler.proxyListener, capture);
41714            handlers.splice(k, 1);
41715          } else if (!listener) {
41716            el.removeEventListener(event, handler.proxyListener, capture);
41717            handlers.splice(k, 1);
41718          }
41719        }
41720      }
41721    }
41722  }
41723
41724  return this;
41725}
41726
41727function once() {
41728  var dom = this;
41729
41730  for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
41731    args[_key7] = arguments[_key7];
41732  }
41733
41734  var eventName = args[0],
41735      targetSelector = args[1],
41736      listener = args[2],
41737      capture = args[3];
41738
41739  if (typeof args[1] === 'function') {
41740    eventName = args[0];
41741    listener = args[1];
41742    capture = args[2];
41743    targetSelector = undefined;
41744  }
41745
41746  function onceHandler() {
41747    for (var _len8 = arguments.length, eventArgs = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
41748      eventArgs[_key8] = arguments[_key8];
41749    }
41750
41751    listener.apply(this, eventArgs);
41752    dom.off(eventName, targetSelector, onceHandler, capture);
41753
41754    if (onceHandler.dom7proxy) {
41755      delete onceHandler.dom7proxy;
41756    }
41757  }
41758
41759  onceHandler.dom7proxy = listener;
41760  return dom.on(eventName, targetSelector, onceHandler, capture);
41761}
41762
41763function trigger() {
41764  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
41765
41766  for (var _len9 = arguments.length, args = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
41767    args[_key9] = arguments[_key9];
41768  }
41769
41770  var events = args[0].split(' ');
41771  var eventData = args[1];
41772
41773  for (var i = 0; i < events.length; i += 1) {
41774    var event = events[i];
41775
41776    for (var j = 0; j < this.length; j += 1) {
41777      var el = this[j];
41778
41779      if (window.CustomEvent) {
41780        var evt = new window.CustomEvent(event, {
41781          detail: eventData,
41782          bubbles: true,
41783          cancelable: true
41784        });
41785        el.dom7EventData = args.filter(function (data, dataIndex) {
41786          return dataIndex > 0;
41787        });
41788        el.dispatchEvent(evt);
41789        el.dom7EventData = [];
41790        delete el.dom7EventData;
41791      }
41792    }
41793  }
41794
41795  return this;
41796}
41797
41798function transitionEnd(callback) {
41799  var dom = this;
41800
41801  function fireCallBack(e) {
41802    if (e.target !== this) return;
41803    callback.call(this, e);
41804    dom.off('transitionend', fireCallBack);
41805  }
41806
41807  if (callback) {
41808    dom.on('transitionend', fireCallBack);
41809  }
41810
41811  return this;
41812}
41813
41814function animationEnd(callback) {
41815  var dom = this;
41816
41817  function fireCallBack(e) {
41818    if (e.target !== this) return;
41819    callback.call(this, e);
41820    dom.off('animationend', fireCallBack);
41821  }
41822
41823  if (callback) {
41824    dom.on('animationend', fireCallBack);
41825  }
41826
41827  return this;
41828}
41829
41830function width() {
41831  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
41832
41833  if (this[0] === window) {
41834    return window.innerWidth;
41835  }
41836
41837  if (this.length > 0) {
41838    return parseFloat(this.css('width'));
41839  }
41840
41841  return null;
41842}
41843
41844function outerWidth(includeMargins) {
41845  if (this.length > 0) {
41846    if (includeMargins) {
41847      var _styles = this.styles();
41848
41849      return this[0].offsetWidth + parseFloat(_styles.getPropertyValue('margin-right')) + parseFloat(_styles.getPropertyValue('margin-left'));
41850    }
41851
41852    return this[0].offsetWidth;
41853  }
41854
41855  return null;
41856}
41857
41858function height() {
41859  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
41860
41861  if (this[0] === window) {
41862    return window.innerHeight;
41863  }
41864
41865  if (this.length > 0) {
41866    return parseFloat(this.css('height'));
41867  }
41868
41869  return null;
41870}
41871
41872function outerHeight(includeMargins) {
41873  if (this.length > 0) {
41874    if (includeMargins) {
41875      var _styles2 = this.styles();
41876
41877      return this[0].offsetHeight + parseFloat(_styles2.getPropertyValue('margin-top')) + parseFloat(_styles2.getPropertyValue('margin-bottom'));
41878    }
41879
41880    return this[0].offsetHeight;
41881  }
41882
41883  return null;
41884}
41885
41886function offset() {
41887  if (this.length > 0) {
41888    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
41889    var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
41890    var el = this[0];
41891    var box = el.getBoundingClientRect();
41892    var body = document.body;
41893    var clientTop = el.clientTop || body.clientTop || 0;
41894    var clientLeft = el.clientLeft || body.clientLeft || 0;
41895    var scrollTop = el === window ? window.scrollY : el.scrollTop;
41896    var scrollLeft = el === window ? window.scrollX : el.scrollLeft;
41897    return {
41898      top: box.top + scrollTop - clientTop,
41899      left: box.left + scrollLeft - clientLeft
41900    };
41901  }
41902
41903  return null;
41904}
41905
41906function hide() {
41907  for (var i = 0; i < this.length; i += 1) {
41908    this[i].style.display = 'none';
41909  }
41910
41911  return this;
41912}
41913
41914function show() {
41915  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
41916
41917  for (var i = 0; i < this.length; i += 1) {
41918    var el = this[i];
41919
41920    if (el.style.display === 'none') {
41921      el.style.display = '';
41922    }
41923
41924    if (window.getComputedStyle(el, null).getPropertyValue('display') === 'none') {
41925      // Still not visible
41926      el.style.display = 'block';
41927    }
41928  }
41929
41930  return this;
41931}
41932
41933function styles() {
41934  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
41935  if (this[0]) return window.getComputedStyle(this[0], null);
41936  return {};
41937}
41938
41939function css(props, value) {
41940  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
41941  var i;
41942
41943  if (arguments.length === 1) {
41944    if (typeof props === 'string') {
41945      // .css('width')
41946      if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);
41947    } else {
41948      // .css({ width: '100px' })
41949      for (i = 0; i < this.length; i += 1) {
41950        for (var _prop in props) {
41951          this[i].style[_prop] = props[_prop];
41952        }
41953      }
41954
41955      return this;
41956    }
41957  }
41958
41959  if (arguments.length === 2 && typeof props === 'string') {
41960    // .css('width', '100px')
41961    for (i = 0; i < this.length; i += 1) {
41962      this[i].style[props] = value;
41963    }
41964
41965    return this;
41966  }
41967
41968  return this;
41969}
41970
41971function each(callback) {
41972  if (!callback) return this;
41973  this.forEach(function (el, index) {
41974    callback.apply(el, [el, index]);
41975  });
41976  return this;
41977}
41978
41979function filter(callback) {
41980  var result = arrayFilter(this, callback);
41981  return $(result);
41982}
41983
41984function html(html) {
41985  if (typeof html === 'undefined') {
41986    return this[0] ? this[0].innerHTML : null;
41987  }
41988
41989  for (var i = 0; i < this.length; i += 1) {
41990    this[i].innerHTML = html;
41991  }
41992
41993  return this;
41994}
41995
41996function text(text) {
41997  if (typeof text === 'undefined') {
41998    return this[0] ? this[0].textContent.trim() : null;
41999  }
42000
42001  for (var i = 0; i < this.length; i += 1) {
42002    this[i].textContent = text;
42003  }
42004
42005  return this;
42006}
42007
42008function is(selector) {
42009  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
42010  var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
42011  var el = this[0];
42012  var compareWith;
42013  var i;
42014  if (!el || typeof selector === 'undefined') return false;
42015
42016  if (typeof selector === 'string') {
42017    if (el.matches) return el.matches(selector);
42018    if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);
42019    if (el.msMatchesSelector) return el.msMatchesSelector(selector);
42020    compareWith = $(selector);
42021
42022    for (i = 0; i < compareWith.length; i += 1) {
42023      if (compareWith[i] === el) return true;
42024    }
42025
42026    return false;
42027  }
42028
42029  if (selector === document) {
42030    return el === document;
42031  }
42032
42033  if (selector === window) {
42034    return el === window;
42035  }
42036
42037  if (selector.nodeType || selector instanceof Dom7) {
42038    compareWith = selector.nodeType ? [selector] : selector;
42039
42040    for (i = 0; i < compareWith.length; i += 1) {
42041      if (compareWith[i] === el) return true;
42042    }
42043
42044    return false;
42045  }
42046
42047  return false;
42048}
42049
42050function index() {
42051  var child = this[0];
42052  var i;
42053
42054  if (child) {
42055    i = 0; // eslint-disable-next-line
42056
42057    while ((child = child.previousSibling) !== null) {
42058      if (child.nodeType === 1) i += 1;
42059    }
42060
42061    return i;
42062  }
42063
42064  return undefined;
42065}
42066
42067function eq(index) {
42068  if (typeof index === 'undefined') return this;
42069  var length = this.length;
42070
42071  if (index > length - 1) {
42072    return $([]);
42073  }
42074
42075  if (index < 0) {
42076    var returnIndex = length + index;
42077    if (returnIndex < 0) return $([]);
42078    return $([this[returnIndex]]);
42079  }
42080
42081  return $([this[index]]);
42082}
42083
42084function append() {
42085  var newChild;
42086  var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
42087
42088  for (var k = 0; k < arguments.length; k += 1) {
42089    newChild = k < 0 || arguments.length <= k ? undefined : arguments[k];
42090
42091    for (var i = 0; i < this.length; i += 1) {
42092      if (typeof newChild === 'string') {
42093        var tempDiv = document.createElement('div');
42094        tempDiv.innerHTML = newChild;
42095
42096        while (tempDiv.firstChild) {
42097          this[i].appendChild(tempDiv.firstChild);
42098        }
42099      } else if (newChild instanceof Dom7) {
42100        for (var j = 0; j < newChild.length; j += 1) {
42101          this[i].appendChild(newChild[j]);
42102        }
42103      } else {
42104        this[i].appendChild(newChild);
42105      }
42106    }
42107  }
42108
42109  return this;
42110}
42111
42112function appendTo(parent) {
42113  $(parent).append(this);
42114  return this;
42115}
42116
42117function prepend(newChild) {
42118  var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
42119  var i;
42120  var j;
42121
42122  for (i = 0; i < this.length; i += 1) {
42123    if (typeof newChild === 'string') {
42124      var tempDiv = document.createElement('div');
42125      tempDiv.innerHTML = newChild;
42126
42127      for (j = tempDiv.childNodes.length - 1; j >= 0; j -= 1) {
42128        this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);
42129      }
42130    } else if (newChild instanceof Dom7) {
42131      for (j = 0; j < newChild.length; j += 1) {
42132        this[i].insertBefore(newChild[j], this[i].childNodes[0]);
42133      }
42134    } else {
42135      this[i].insertBefore(newChild, this[i].childNodes[0]);
42136    }
42137  }
42138
42139  return this;
42140}
42141
42142function prependTo(parent) {
42143  $(parent).prepend(this);
42144  return this;
42145}
42146
42147function insertBefore(selector) {
42148  var before = $(selector);
42149
42150  for (var i = 0; i < this.length; i += 1) {
42151    if (before.length === 1) {
42152      before[0].parentNode.insertBefore(this[i], before[0]);
42153    } else if (before.length > 1) {
42154      for (var j = 0; j < before.length; j += 1) {
42155        before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);
42156      }
42157    }
42158  }
42159}
42160
42161function insertAfter(selector) {
42162  var after = $(selector);
42163
42164  for (var i = 0; i < this.length; i += 1) {
42165    if (after.length === 1) {
42166      after[0].parentNode.insertBefore(this[i], after[0].nextSibling);
42167    } else if (after.length > 1) {
42168      for (var j = 0; j < after.length; j += 1) {
42169        after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);
42170      }
42171    }
42172  }
42173}
42174
42175function next(selector) {
42176  if (this.length > 0) {
42177    if (selector) {
42178      if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) {
42179        return $([this[0].nextElementSibling]);
42180      }
42181
42182      return $([]);
42183    }
42184
42185    if (this[0].nextElementSibling) return $([this[0].nextElementSibling]);
42186    return $([]);
42187  }
42188
42189  return $([]);
42190}
42191
42192function nextAll(selector) {
42193  var nextEls = [];
42194  var el = this[0];
42195  if (!el) return $([]);
42196
42197  while (el.nextElementSibling) {
42198    var _next = el.nextElementSibling; // eslint-disable-line
42199
42200    if (selector) {
42201      if ($(_next).is(selector)) nextEls.push(_next);
42202    } else nextEls.push(_next);
42203
42204    el = _next;
42205  }
42206
42207  return $(nextEls);
42208}
42209
42210function prev(selector) {
42211  if (this.length > 0) {
42212    var el = this[0];
42213
42214    if (selector) {
42215      if (el.previousElementSibling && $(el.previousElementSibling).is(selector)) {
42216        return $([el.previousElementSibling]);
42217      }
42218
42219      return $([]);
42220    }
42221
42222    if (el.previousElementSibling) return $([el.previousElementSibling]);
42223    return $([]);
42224  }
42225
42226  return $([]);
42227}
42228
42229function prevAll(selector) {
42230  var prevEls = [];
42231  var el = this[0];
42232  if (!el) return $([]);
42233
42234  while (el.previousElementSibling) {
42235    var _prev = el.previousElementSibling; // eslint-disable-line
42236
42237    if (selector) {
42238      if ($(_prev).is(selector)) prevEls.push(_prev);
42239    } else prevEls.push(_prev);
42240
42241    el = _prev;
42242  }
42243
42244  return $(prevEls);
42245}
42246
42247function siblings(selector) {
42248  return this.nextAll(selector).add(this.prevAll(selector));
42249}
42250
42251function parent(selector) {
42252  var parents = []; // eslint-disable-line
42253
42254  for (var i = 0; i < this.length; i += 1) {
42255    if (this[i].parentNode !== null) {
42256      if (selector) {
42257        if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);
42258      } else {
42259        parents.push(this[i].parentNode);
42260      }
42261    }
42262  }
42263
42264  return $(parents);
42265}
42266
42267function parents(selector) {
42268  var parents = []; // eslint-disable-line
42269
42270  for (var i = 0; i < this.length; i += 1) {
42271    var _parent = this[i].parentNode; // eslint-disable-line
42272
42273    while (_parent) {
42274      if (selector) {
42275        if ($(_parent).is(selector)) parents.push(_parent);
42276      } else {
42277        parents.push(_parent);
42278      }
42279
42280      _parent = _parent.parentNode;
42281    }
42282  }
42283
42284  return $(parents);
42285}
42286
42287function closest(selector) {
42288  var closest = this; // eslint-disable-line
42289
42290  if (typeof selector === 'undefined') {
42291    return $([]);
42292  }
42293
42294  if (!closest.is(selector)) {
42295    closest = closest.parents(selector).eq(0);
42296  }
42297
42298  return closest;
42299}
42300
42301function find(selector) {
42302  var foundElements = [];
42303
42304  for (var i = 0; i < this.length; i += 1) {
42305    var found = this[i].querySelectorAll(selector);
42306
42307    for (var j = 0; j < found.length; j += 1) {
42308      foundElements.push(found[j]);
42309    }
42310  }
42311
42312  return $(foundElements);
42313}
42314
42315function children(selector) {
42316  var children = []; // eslint-disable-line
42317
42318  for (var i = 0; i < this.length; i += 1) {
42319    var childNodes = this[i].children;
42320
42321    for (var j = 0; j < childNodes.length; j += 1) {
42322      if (!selector || $(childNodes[j]).is(selector)) {
42323        children.push(childNodes[j]);
42324      }
42325    }
42326  }
42327
42328  return $(children);
42329}
42330
42331function remove() {
42332  for (var i = 0; i < this.length; i += 1) {
42333    if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);
42334  }
42335
42336  return this;
42337}
42338
42339function detach() {
42340  return this.remove();
42341}
42342
42343function add() {
42344  var dom = this;
42345  var i;
42346  var j;
42347
42348  for (var _len10 = arguments.length, els = new Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
42349    els[_key10] = arguments[_key10];
42350  }
42351
42352  for (i = 0; i < els.length; i += 1) {
42353    var toAdd = $(els[i]);
42354
42355    for (j = 0; j < toAdd.length; j += 1) {
42356      dom.push(toAdd[j]);
42357    }
42358  }
42359
42360  return dom;
42361}
42362
42363function empty() {
42364  for (var i = 0; i < this.length; i += 1) {
42365    var el = this[i];
42366
42367    if (el.nodeType === 1) {
42368      for (var j = 0; j < el.childNodes.length; j += 1) {
42369        if (el.childNodes[j].parentNode) {
42370          el.childNodes[j].parentNode.removeChild(el.childNodes[j]);
42371        }
42372      }
42373
42374      el.textContent = '';
42375    }
42376  }
42377
42378  return this;
42379}
42380
42381function scrollTo() {
42382  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
42383
42384  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
42385    args[_key] = arguments[_key];
42386  }
42387
42388  var left = args[0],
42389      top = args[1],
42390      duration = args[2],
42391      easing = args[3],
42392      callback = args[4];
42393
42394  if (args.length === 4 && typeof easing === 'function') {
42395    callback = easing;
42396    left = args[0];
42397    top = args[1];
42398    duration = args[2];
42399    callback = args[3];
42400    easing = args[4];
42401  }
42402
42403  if (typeof easing === 'undefined') easing = 'swing';
42404  return this.each(function animate() {
42405    var el = this;
42406    var currentTop;
42407    var currentLeft;
42408    var maxTop;
42409    var maxLeft;
42410    var newTop;
42411    var newLeft;
42412    var scrollTop; // eslint-disable-line
42413
42414    var scrollLeft; // eslint-disable-line
42415
42416    var animateTop = top > 0 || top === 0;
42417    var animateLeft = left > 0 || left === 0;
42418
42419    if (typeof easing === 'undefined') {
42420      easing = 'swing';
42421    }
42422
42423    if (animateTop) {
42424      currentTop = el.scrollTop;
42425
42426      if (!duration) {
42427        el.scrollTop = top;
42428      }
42429    }
42430
42431    if (animateLeft) {
42432      currentLeft = el.scrollLeft;
42433
42434      if (!duration) {
42435        el.scrollLeft = left;
42436      }
42437    }
42438
42439    if (!duration) return;
42440
42441    if (animateTop) {
42442      maxTop = el.scrollHeight - el.offsetHeight;
42443      newTop = Math.max(Math.min(top, maxTop), 0);
42444    }
42445
42446    if (animateLeft) {
42447      maxLeft = el.scrollWidth - el.offsetWidth;
42448      newLeft = Math.max(Math.min(left, maxLeft), 0);
42449    }
42450
42451    var startTime = null;
42452    if (animateTop && newTop === currentTop) animateTop = false;
42453    if (animateLeft && newLeft === currentLeft) animateLeft = false;
42454
42455    function render(time) {
42456      if (time === void 0) {
42457        time = new Date().getTime();
42458      }
42459
42460      if (startTime === null) {
42461        startTime = time;
42462      }
42463
42464      var progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
42465      var easeProgress = easing === 'linear' ? progress : 0.5 - Math.cos(progress * Math.PI) / 2;
42466      var done;
42467      if (animateTop) scrollTop = currentTop + easeProgress * (newTop - currentTop);
42468      if (animateLeft) scrollLeft = currentLeft + easeProgress * (newLeft - currentLeft);
42469
42470      if (animateTop && newTop > currentTop && scrollTop >= newTop) {
42471        el.scrollTop = newTop;
42472        done = true;
42473      }
42474
42475      if (animateTop && newTop < currentTop && scrollTop <= newTop) {
42476        el.scrollTop = newTop;
42477        done = true;
42478      }
42479
42480      if (animateLeft && newLeft > currentLeft && scrollLeft >= newLeft) {
42481        el.scrollLeft = newLeft;
42482        done = true;
42483      }
42484
42485      if (animateLeft && newLeft < currentLeft && scrollLeft <= newLeft) {
42486        el.scrollLeft = newLeft;
42487        done = true;
42488      }
42489
42490      if (done) {
42491        if (callback) callback();
42492        return;
42493      }
42494
42495      if (animateTop) el.scrollTop = scrollTop;
42496      if (animateLeft) el.scrollLeft = scrollLeft;
42497      window.requestAnimationFrame(render);
42498    }
42499
42500    window.requestAnimationFrame(render);
42501  });
42502} // scrollTop(top, duration, easing, callback) {
42503
42504
42505function scrollTop() {
42506  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
42507    args[_key2] = arguments[_key2];
42508  }
42509
42510  var top = args[0],
42511      duration = args[1],
42512      easing = args[2],
42513      callback = args[3];
42514
42515  if (args.length === 3 && typeof easing === 'function') {
42516    top = args[0];
42517    duration = args[1];
42518    callback = args[2];
42519    easing = args[3];
42520  }
42521
42522  var dom = this;
42523
42524  if (typeof top === 'undefined') {
42525    if (dom.length > 0) return dom[0].scrollTop;
42526    return null;
42527  }
42528
42529  return dom.scrollTo(undefined, top, duration, easing, callback);
42530}
42531
42532function scrollLeft() {
42533  for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
42534    args[_key3] = arguments[_key3];
42535  }
42536
42537  var left = args[0],
42538      duration = args[1],
42539      easing = args[2],
42540      callback = args[3];
42541
42542  if (args.length === 3 && typeof easing === 'function') {
42543    left = args[0];
42544    duration = args[1];
42545    callback = args[2];
42546    easing = args[3];
42547  }
42548
42549  var dom = this;
42550
42551  if (typeof left === 'undefined') {
42552    if (dom.length > 0) return dom[0].scrollLeft;
42553    return null;
42554  }
42555
42556  return dom.scrollTo(left, undefined, duration, easing, callback);
42557}
42558
42559function animate(initialProps, initialParams) {
42560  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
42561  var els = this;
42562  var a = {
42563    props: Object.assign({}, initialProps),
42564    params: Object.assign({
42565      duration: 300,
42566      easing: 'swing' // or 'linear'
42567
42568      /* Callbacks
42569      begin(elements)
42570      complete(elements)
42571      progress(elements, complete, remaining, start, tweenValue)
42572      */
42573
42574    }, initialParams),
42575    elements: els,
42576    animating: false,
42577    que: [],
42578    easingProgress: function easingProgress(easing, progress) {
42579      if (easing === 'swing') {
42580        return 0.5 - Math.cos(progress * Math.PI) / 2;
42581      }
42582
42583      if (typeof easing === 'function') {
42584        return easing(progress);
42585      }
42586
42587      return progress;
42588    },
42589    stop: function stop() {
42590      if (a.frameId) {
42591        window.cancelAnimationFrame(a.frameId);
42592      }
42593
42594      a.animating = false;
42595      a.elements.each(function (el) {
42596        var element = el;
42597        delete element.dom7AnimateInstance;
42598      });
42599      a.que = [];
42600    },
42601    done: function done(complete) {
42602      a.animating = false;
42603      a.elements.each(function (el) {
42604        var element = el;
42605        delete element.dom7AnimateInstance;
42606      });
42607      if (complete) complete(els);
42608
42609      if (a.que.length > 0) {
42610        var que = a.que.shift();
42611        a.animate(que[0], que[1]);
42612      }
42613    },
42614    animate: function animate(props, params) {
42615      if (a.animating) {
42616        a.que.push([props, params]);
42617        return a;
42618      }
42619
42620      var elements = []; // Define & Cache Initials & Units
42621
42622      a.elements.each(function (el, index) {
42623        var initialFullValue;
42624        var initialValue;
42625        var unit;
42626        var finalValue;
42627        var finalFullValue;
42628        if (!el.dom7AnimateInstance) a.elements[index].dom7AnimateInstance = a;
42629        elements[index] = {
42630          container: el
42631        };
42632        Object.keys(props).forEach(function (prop) {
42633          initialFullValue = window.getComputedStyle(el, null).getPropertyValue(prop).replace(',', '.');
42634          initialValue = parseFloat(initialFullValue);
42635          unit = initialFullValue.replace(initialValue, '');
42636          finalValue = parseFloat(props[prop]);
42637          finalFullValue = props[prop] + unit;
42638          elements[index][prop] = {
42639            initialFullValue: initialFullValue,
42640            initialValue: initialValue,
42641            unit: unit,
42642            finalValue: finalValue,
42643            finalFullValue: finalFullValue,
42644            currentValue: initialValue
42645          };
42646        });
42647      });
42648      var startTime = null;
42649      var time;
42650      var elementsDone = 0;
42651      var propsDone = 0;
42652      var done;
42653      var began = false;
42654      a.animating = true;
42655
42656      function render() {
42657        time = new Date().getTime();
42658        var progress;
42659        var easeProgress; // let el;
42660
42661        if (!began) {
42662          began = true;
42663          if (params.begin) params.begin(els);
42664        }
42665
42666        if (startTime === null) {
42667          startTime = time;
42668        }
42669
42670        if (params.progress) {
42671          // eslint-disable-next-line
42672          params.progress(els, Math.max(Math.min((time - startTime) / params.duration, 1), 0), startTime + params.duration - time < 0 ? 0 : startTime + params.duration - time, startTime);
42673        }
42674
42675        elements.forEach(function (element) {
42676          var el = element;
42677          if (done || el.done) return;
42678          Object.keys(props).forEach(function (prop) {
42679            if (done || el.done) return;
42680            progress = Math.max(Math.min((time - startTime) / params.duration, 1), 0);
42681            easeProgress = a.easingProgress(params.easing, progress);
42682            var _el$prop = el[prop],
42683                initialValue = _el$prop.initialValue,
42684                finalValue = _el$prop.finalValue,
42685                unit = _el$prop.unit;
42686            el[prop].currentValue = initialValue + easeProgress * (finalValue - initialValue);
42687            var currentValue = el[prop].currentValue;
42688
42689            if (finalValue > initialValue && currentValue >= finalValue || finalValue < initialValue && currentValue <= finalValue) {
42690              el.container.style[prop] = finalValue + unit;
42691              propsDone += 1;
42692
42693              if (propsDone === Object.keys(props).length) {
42694                el.done = true;
42695                elementsDone += 1;
42696              }
42697
42698              if (elementsDone === elements.length) {
42699                done = true;
42700              }
42701            }
42702
42703            if (done) {
42704              a.done(params.complete);
42705              return;
42706            }
42707
42708            el.container.style[prop] = currentValue + unit;
42709          });
42710        });
42711        if (done) return; // Then call
42712
42713        a.frameId = window.requestAnimationFrame(render);
42714      }
42715
42716      a.frameId = window.requestAnimationFrame(render);
42717      return a;
42718    }
42719  };
42720
42721  if (a.elements.length === 0) {
42722    return els;
42723  }
42724
42725  var animateInstance;
42726
42727  for (var i = 0; i < a.elements.length; i += 1) {
42728    if (a.elements[i].dom7AnimateInstance) {
42729      animateInstance = a.elements[i].dom7AnimateInstance;
42730    } else a.elements[i].dom7AnimateInstance = a;
42731  }
42732
42733  if (!animateInstance) {
42734    animateInstance = a;
42735  }
42736
42737  if (initialProps === 'stop') {
42738    animateInstance.stop();
42739  } else {
42740    animateInstance.animate(a.props, a.params);
42741  }
42742
42743  return els;
42744}
42745
42746function stop() {
42747  var els = this;
42748
42749  for (var i = 0; i < els.length; i += 1) {
42750    if (els[i].dom7AnimateInstance) {
42751      els[i].dom7AnimateInstance.stop();
42752    }
42753  }
42754}
42755
42756var noTrigger = 'resize scroll'.split(' ');
42757
42758function shortcut(name) {
42759  function eventHandler() {
42760    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
42761      args[_key] = arguments[_key];
42762    }
42763
42764    if (typeof args[0] === 'undefined') {
42765      for (var i = 0; i < this.length; i += 1) {
42766        if (noTrigger.indexOf(name) < 0) {
42767          if (name in this[i]) this[i][name]();else {
42768            $(this[i]).trigger(name);
42769          }
42770        }
42771      }
42772
42773      return this;
42774    }
42775
42776    return this.on.apply(this, [name].concat(args));
42777  }
42778
42779  return eventHandler;
42780}
42781
42782var click = shortcut('click');
42783var blur = shortcut('blur');
42784var focus = shortcut('focus');
42785var focusin = shortcut('focusin');
42786var focusout = shortcut('focusout');
42787var keyup = shortcut('keyup');
42788var keydown = shortcut('keydown');
42789var keypress = shortcut('keypress');
42790var submit = shortcut('submit');
42791var change = shortcut('change');
42792var mousedown = shortcut('mousedown');
42793var mousemove = shortcut('mousemove');
42794var mouseup = shortcut('mouseup');
42795var mouseenter = shortcut('mouseenter');
42796var mouseleave = shortcut('mouseleave');
42797var mouseout = shortcut('mouseout');
42798var mouseover = shortcut('mouseover');
42799var touchstart = shortcut('touchstart');
42800var touchend = shortcut('touchend');
42801var touchmove = shortcut('touchmove');
42802var resize = shortcut('resize');
42803var scroll = shortcut('scroll');
42804
42805/* unused harmony default export */ var _unused_webpack_default_export = ($);
42806
42807
42808
42809/***/ }),
42810/* 167 */
42811/***/ (function(module, __webpack_exports__, __webpack_require__) {
42812
42813"use strict";
42814/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return getDevice; });
42815/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
42816/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__get_support__ = __webpack_require__(146);
42817
42818
42819var device;
42820
42821function calcDevice(_temp) {
42822  var _ref = _temp === void 0 ? {} : _temp,
42823      userAgent = _ref.userAgent;
42824
42825  var support = Object(__WEBPACK_IMPORTED_MODULE_1__get_support__["a" /* getSupport */])();
42826  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
42827  var platform = window.navigator.platform;
42828  var ua = userAgent || window.navigator.userAgent;
42829  var device = {
42830    ios: false,
42831    android: false
42832  };
42833  var screenWidth = window.screen.width;
42834  var screenHeight = window.screen.height;
42835  var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
42836
42837  var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
42838  var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
42839  var iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
42840  var windows = platform === 'Win32';
42841  var macos = platform === 'MacIntel'; // iPadOs 13 fix
42842
42843  var iPadScreens = ['1024x1366', '1366x1024', '834x1194', '1194x834', '834x1112', '1112x834', '768x1024', '1024x768', '820x1180', '1180x820', '810x1080', '1080x810'];
42844
42845  if (!ipad && macos && support.touch && iPadScreens.indexOf(screenWidth + "x" + screenHeight) >= 0) {
42846    ipad = ua.match(/(Version)\/([\d.]+)/);
42847    if (!ipad) ipad = [0, 1, '13_0_0'];
42848    macos = false;
42849  } // Android
42850
42851
42852  if (android && !windows) {
42853    device.os = 'android';
42854    device.android = true;
42855  }
42856
42857  if (ipad || iphone || ipod) {
42858    device.os = 'ios';
42859    device.ios = true;
42860  } // Export object
42861
42862
42863  return device;
42864}
42865
42866function getDevice(overrides) {
42867  if (overrides === void 0) {
42868    overrides = {};
42869  }
42870
42871  if (!device) {
42872    device = calcDevice(overrides);
42873  }
42874
42875  return device;
42876}
42877
42878
42879
42880/***/ }),
42881/* 168 */
42882/***/ (function(module, __webpack_exports__, __webpack_require__) {
42883
42884"use strict";
42885/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return getBrowser; });
42886/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
42887
42888var browser;
42889
42890function calcBrowser() {
42891  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
42892
42893  function isSafari() {
42894    var ua = window.navigator.userAgent.toLowerCase();
42895    return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0;
42896  }
42897
42898  return {
42899    isEdge: !!window.navigator.userAgent.match(/Edge/g),
42900    isSafari: isSafari(),
42901    isWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent)
42902  };
42903}
42904
42905function getBrowser() {
42906  if (!browser) {
42907    browser = calcBrowser();
42908  }
42909
42910  return browser;
42911}
42912
42913
42914
42915/***/ }),
42916/* 169 */
42917/***/ (function(module, __webpack_exports__, __webpack_require__) {
42918
42919"use strict";
42920/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
42921/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
42922
42923
42924
42925var supportsResizeObserver = function supportsResizeObserver() {
42926  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
42927  return typeof window.ResizeObserver !== 'undefined';
42928};
42929
42930/* harmony default export */ __webpack_exports__["a"] = ({
42931  name: 'resize',
42932  create: function create() {
42933    var swiper = this;
42934    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["e" /* extend */])(swiper, {
42935      resize: {
42936        observer: null,
42937        createObserver: function createObserver() {
42938          if (!swiper || swiper.destroyed || !swiper.initialized) return;
42939          swiper.resize.observer = new ResizeObserver(function (entries) {
42940            var width = swiper.width,
42941                height = swiper.height;
42942            var newWidth = width;
42943            var newHeight = height;
42944            entries.forEach(function (_ref) {
42945              var contentBoxSize = _ref.contentBoxSize,
42946                  contentRect = _ref.contentRect,
42947                  target = _ref.target;
42948              if (target && target !== swiper.el) return;
42949              newWidth = contentRect ? contentRect.width : (contentBoxSize[0] || contentBoxSize).inlineSize;
42950              newHeight = contentRect ? contentRect.height : (contentBoxSize[0] || contentBoxSize).blockSize;
42951            });
42952
42953            if (newWidth !== width || newHeight !== height) {
42954              swiper.resize.resizeHandler();
42955            }
42956          });
42957          swiper.resize.observer.observe(swiper.el);
42958        },
42959        removeObserver: function removeObserver() {
42960          if (swiper.resize.observer && swiper.resize.observer.unobserve && swiper.el) {
42961            swiper.resize.observer.unobserve(swiper.el);
42962            swiper.resize.observer = null;
42963          }
42964        },
42965        resizeHandler: function resizeHandler() {
42966          if (!swiper || swiper.destroyed || !swiper.initialized) return;
42967          swiper.emit('beforeResize');
42968          swiper.emit('resize');
42969        },
42970        orientationChangeHandler: function orientationChangeHandler() {
42971          if (!swiper || swiper.destroyed || !swiper.initialized) return;
42972          swiper.emit('orientationchange');
42973        }
42974      }
42975    });
42976  },
42977  on: {
42978    init: function init(swiper) {
42979      var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
42980
42981      if (swiper.params.resizeObserver && supportsResizeObserver()) {
42982        swiper.resize.createObserver();
42983        return;
42984      } // Emit resize
42985
42986
42987      window.addEventListener('resize', swiper.resize.resizeHandler); // Emit orientationchange
42988
42989      window.addEventListener('orientationchange', swiper.resize.orientationChangeHandler);
42990    },
42991    destroy: function destroy(swiper) {
42992      var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
42993      swiper.resize.removeObserver();
42994      window.removeEventListener('resize', swiper.resize.resizeHandler);
42995      window.removeEventListener('orientationchange', swiper.resize.orientationChangeHandler);
42996    }
42997  }
42998});
42999
43000/***/ }),
43001/* 170 */
43002/***/ (function(module, __webpack_exports__, __webpack_require__) {
43003
43004"use strict";
43005/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
43006/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
43007function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
43008
43009
43010
43011var Observer = {
43012  attach: function attach(target, options) {
43013    if (options === void 0) {
43014      options = {};
43015    }
43016
43017    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
43018    var swiper = this;
43019    var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
43020    var observer = new ObserverFunc(function (mutations) {
43021      // The observerUpdate event should only be triggered
43022      // once despite the number of mutations.  Additional
43023      // triggers are redundant and are very costly
43024      if (mutations.length === 1) {
43025        swiper.emit('observerUpdate', mutations[0]);
43026        return;
43027      }
43028
43029      var observerUpdate = function observerUpdate() {
43030        swiper.emit('observerUpdate', mutations[0]);
43031      };
43032
43033      if (window.requestAnimationFrame) {
43034        window.requestAnimationFrame(observerUpdate);
43035      } else {
43036        window.setTimeout(observerUpdate, 0);
43037      }
43038    });
43039    observer.observe(target, {
43040      attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
43041      childList: typeof options.childList === 'undefined' ? true : options.childList,
43042      characterData: typeof options.characterData === 'undefined' ? true : options.characterData
43043    });
43044    swiper.observer.observers.push(observer);
43045  },
43046  init: function init() {
43047    var swiper = this;
43048    if (!swiper.support.observer || !swiper.params.observer) return;
43049
43050    if (swiper.params.observeParents) {
43051      var containerParents = swiper.$el.parents();
43052
43053      for (var i = 0; i < containerParents.length; i += 1) {
43054        swiper.observer.attach(containerParents[i]);
43055      }
43056    } // Observe container
43057
43058
43059    swiper.observer.attach(swiper.$el[0], {
43060      childList: swiper.params.observeSlideChildren
43061    }); // Observe wrapper
43062
43063    swiper.observer.attach(swiper.$wrapperEl[0], {
43064      attributes: false
43065    });
43066  },
43067  destroy: function destroy() {
43068    var swiper = this;
43069    swiper.observer.observers.forEach(function (observer) {
43070      observer.disconnect();
43071    });
43072    swiper.observer.observers = [];
43073  }
43074};
43075/* harmony default export */ __webpack_exports__["a"] = ({
43076  name: 'observer',
43077  params: {
43078    observer: false,
43079    observeParents: false,
43080    observeSlideChildren: false
43081  },
43082  create: function create() {
43083    var swiper = this;
43084    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["a" /* bindModuleMethods */])(swiper, {
43085      observer: _extends({}, Observer, {
43086        observers: []
43087      })
43088    });
43089  },
43090  on: {
43091    init: function init(swiper) {
43092      swiper.observer.init();
43093    },
43094    destroy: function destroy(swiper) {
43095      swiper.observer.destroy();
43096    }
43097  }
43098});
43099
43100/***/ }),
43101/* 171 */
43102/***/ (function(module, __webpack_exports__, __webpack_require__) {
43103
43104"use strict";
43105/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_utils__ = __webpack_require__(1);
43106
43107/* harmony default export */ __webpack_exports__["a"] = ({
43108  useParams: function useParams(instanceParams) {
43109    var instance = this;
43110    if (!instance.modules) return;
43111    Object.keys(instance.modules).forEach(function (moduleName) {
43112      var module = instance.modules[moduleName]; // Extend params
43113
43114      if (module.params) {
43115        Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["e" /* extend */])(instanceParams, module.params);
43116      }
43117    });
43118  },
43119  useModules: function useModules(modulesParams) {
43120    if (modulesParams === void 0) {
43121      modulesParams = {};
43122    }
43123
43124    var instance = this;
43125    if (!instance.modules) return;
43126    Object.keys(instance.modules).forEach(function (moduleName) {
43127      var module = instance.modules[moduleName];
43128      var moduleParams = modulesParams[moduleName] || {}; // Add event listeners
43129
43130      if (module.on && instance.on) {
43131        Object.keys(module.on).forEach(function (moduleEventName) {
43132          instance.on(moduleEventName, module.on[moduleEventName]);
43133        });
43134      } // Module create callback
43135
43136
43137      if (module.create) {
43138        module.create.bind(instance)(moduleParams);
43139      }
43140    });
43141  }
43142});
43143
43144/***/ }),
43145/* 172 */
43146/***/ (function(module, __webpack_exports__, __webpack_require__) {
43147
43148"use strict";
43149/* eslint-disable no-underscore-dangle */
43150/* harmony default export */ __webpack_exports__["a"] = ({
43151  on: function on(events, handler, priority) {
43152    var self = this;
43153    if (typeof handler !== 'function') return self;
43154    var method = priority ? 'unshift' : 'push';
43155    events.split(' ').forEach(function (event) {
43156      if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
43157      self.eventsListeners[event][method](handler);
43158    });
43159    return self;
43160  },
43161  once: function once(events, handler, priority) {
43162    var self = this;
43163    if (typeof handler !== 'function') return self;
43164
43165    function onceHandler() {
43166      self.off(events, onceHandler);
43167
43168      if (onceHandler.__emitterProxy) {
43169        delete onceHandler.__emitterProxy;
43170      }
43171
43172      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
43173        args[_key] = arguments[_key];
43174      }
43175
43176      handler.apply(self, args);
43177    }
43178
43179    onceHandler.__emitterProxy = handler;
43180    return self.on(events, onceHandler, priority);
43181  },
43182  onAny: function onAny(handler, priority) {
43183    var self = this;
43184    if (typeof handler !== 'function') return self;
43185    var method = priority ? 'unshift' : 'push';
43186
43187    if (self.eventsAnyListeners.indexOf(handler) < 0) {
43188      self.eventsAnyListeners[method](handler);
43189    }
43190
43191    return self;
43192  },
43193  offAny: function offAny(handler) {
43194    var self = this;
43195    if (!self.eventsAnyListeners) return self;
43196    var index = self.eventsAnyListeners.indexOf(handler);
43197
43198    if (index >= 0) {
43199      self.eventsAnyListeners.splice(index, 1);
43200    }
43201
43202    return self;
43203  },
43204  off: function off(events, handler) {
43205    var self = this;
43206    if (!self.eventsListeners) return self;
43207    events.split(' ').forEach(function (event) {
43208      if (typeof handler === 'undefined') {
43209        self.eventsListeners[event] = [];
43210      } else if (self.eventsListeners[event]) {
43211        self.eventsListeners[event].forEach(function (eventHandler, index) {
43212          if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler) {
43213            self.eventsListeners[event].splice(index, 1);
43214          }
43215        });
43216      }
43217    });
43218    return self;
43219  },
43220  emit: function emit() {
43221    var self = this;
43222    if (!self.eventsListeners) return self;
43223    var events;
43224    var data;
43225    var context;
43226
43227    for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
43228      args[_key2] = arguments[_key2];
43229    }
43230
43231    if (typeof args[0] === 'string' || Array.isArray(args[0])) {
43232      events = args[0];
43233      data = args.slice(1, args.length);
43234      context = self;
43235    } else {
43236      events = args[0].events;
43237      data = args[0].data;
43238      context = args[0].context || self;
43239    }
43240
43241    data.unshift(context);
43242    var eventsArray = Array.isArray(events) ? events : events.split(' ');
43243    eventsArray.forEach(function (event) {
43244      if (self.eventsAnyListeners && self.eventsAnyListeners.length) {
43245        self.eventsAnyListeners.forEach(function (eventHandler) {
43246          eventHandler.apply(context, [event].concat(data));
43247        });
43248      }
43249
43250      if (self.eventsListeners && self.eventsListeners[event]) {
43251        self.eventsListeners[event].forEach(function (eventHandler) {
43252          eventHandler.apply(context, data);
43253        });
43254      }
43255    });
43256    return self;
43257  }
43258});
43259
43260/***/ }),
43261/* 173 */
43262/***/ (function(module, __webpack_exports__, __webpack_require__) {
43263
43264"use strict";
43265/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__updateSize__ = __webpack_require__(174);
43266/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__updateSlides__ = __webpack_require__(175);
43267/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__updateAutoHeight__ = __webpack_require__(176);
43268/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__updateSlidesOffset__ = __webpack_require__(177);
43269/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__updateSlidesProgress__ = __webpack_require__(178);
43270/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__updateProgress__ = __webpack_require__(179);
43271/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__updateSlidesClasses__ = __webpack_require__(180);
43272/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__updateActiveIndex__ = __webpack_require__(181);
43273/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__updateClickedSlide__ = __webpack_require__(182);
43274
43275
43276
43277
43278
43279
43280
43281
43282
43283/* harmony default export */ __webpack_exports__["a"] = ({
43284  updateSize: __WEBPACK_IMPORTED_MODULE_0__updateSize__["a" /* default */],
43285  updateSlides: __WEBPACK_IMPORTED_MODULE_1__updateSlides__["a" /* default */],
43286  updateAutoHeight: __WEBPACK_IMPORTED_MODULE_2__updateAutoHeight__["a" /* default */],
43287  updateSlidesOffset: __WEBPACK_IMPORTED_MODULE_3__updateSlidesOffset__["a" /* default */],
43288  updateSlidesProgress: __WEBPACK_IMPORTED_MODULE_4__updateSlidesProgress__["a" /* default */],
43289  updateProgress: __WEBPACK_IMPORTED_MODULE_5__updateProgress__["a" /* default */],
43290  updateSlidesClasses: __WEBPACK_IMPORTED_MODULE_6__updateSlidesClasses__["a" /* default */],
43291  updateActiveIndex: __WEBPACK_IMPORTED_MODULE_7__updateActiveIndex__["a" /* default */],
43292  updateClickedSlide: __WEBPACK_IMPORTED_MODULE_8__updateClickedSlide__["a" /* default */]
43293});
43294
43295/***/ }),
43296/* 174 */
43297/***/ (function(module, __webpack_exports__, __webpack_require__) {
43298
43299"use strict";
43300/* harmony export (immutable) */ __webpack_exports__["a"] = updateSize;
43301/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_utils__ = __webpack_require__(1);
43302
43303function updateSize() {
43304  var swiper = this;
43305  var width;
43306  var height;
43307  var $el = swiper.$el;
43308
43309  if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {
43310    width = swiper.params.width;
43311  } else {
43312    width = $el[0].clientWidth;
43313  }
43314
43315  if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {
43316    height = swiper.params.height;
43317  } else {
43318    height = $el[0].clientHeight;
43319  }
43320
43321  if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) {
43322    return;
43323  } // Subtract paddings
43324
43325
43326  width = width - parseInt($el.css('padding-left') || 0, 10) - parseInt($el.css('padding-right') || 0, 10);
43327  height = height - parseInt($el.css('padding-top') || 0, 10) - parseInt($el.css('padding-bottom') || 0, 10);
43328  if (Number.isNaN(width)) width = 0;
43329  if (Number.isNaN(height)) height = 0;
43330  Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["e" /* extend */])(swiper, {
43331    width: width,
43332    height: height,
43333    size: swiper.isHorizontal() ? width : height
43334  });
43335}
43336
43337/***/ }),
43338/* 175 */
43339/***/ (function(module, __webpack_exports__, __webpack_require__) {
43340
43341"use strict";
43342/* harmony export (immutable) */ __webpack_exports__["a"] = updateSlides;
43343/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_utils__ = __webpack_require__(1);
43344
43345function updateSlides() {
43346  var swiper = this;
43347
43348  function getDirectionLabel(property) {
43349    if (swiper.isHorizontal()) {
43350      return property;
43351    } // prettier-ignore
43352
43353
43354    return {
43355      'width': 'height',
43356      'margin-top': 'margin-left',
43357      'margin-bottom ': 'margin-right',
43358      'margin-left': 'margin-top',
43359      'margin-right': 'margin-bottom',
43360      'padding-left': 'padding-top',
43361      'padding-right': 'padding-bottom',
43362      'marginRight': 'marginBottom'
43363    }[property];
43364  }
43365
43366  function getDirectionPropertyValue(node, label) {
43367    return parseFloat(node.getPropertyValue(getDirectionLabel(label)) || 0);
43368  }
43369
43370  var params = swiper.params;
43371  var $wrapperEl = swiper.$wrapperEl,
43372      swiperSize = swiper.size,
43373      rtl = swiper.rtlTranslate,
43374      wrongRTL = swiper.wrongRTL;
43375  var isVirtual = swiper.virtual && params.virtual.enabled;
43376  var previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
43377  var slides = $wrapperEl.children("." + swiper.params.slideClass);
43378  var slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
43379  var snapGrid = [];
43380  var slidesGrid = [];
43381  var slidesSizesGrid = [];
43382  var offsetBefore = params.slidesOffsetBefore;
43383
43384  if (typeof offsetBefore === 'function') {
43385    offsetBefore = params.slidesOffsetBefore.call(swiper);
43386  }
43387
43388  var offsetAfter = params.slidesOffsetAfter;
43389
43390  if (typeof offsetAfter === 'function') {
43391    offsetAfter = params.slidesOffsetAfter.call(swiper);
43392  }
43393
43394  var previousSnapGridLength = swiper.snapGrid.length;
43395  var previousSlidesGridLength = swiper.slidesGrid.length;
43396  var spaceBetween = params.spaceBetween;
43397  var slidePosition = -offsetBefore;
43398  var prevSlideSize = 0;
43399  var index = 0;
43400
43401  if (typeof swiperSize === 'undefined') {
43402    return;
43403  }
43404
43405  if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
43406    spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;
43407  }
43408
43409  swiper.virtualSize = -spaceBetween; // reset margins
43410
43411  if (rtl) slides.css({
43412    marginLeft: '',
43413    marginBottom: '',
43414    marginTop: ''
43415  });else slides.css({
43416    marginRight: '',
43417    marginBottom: '',
43418    marginTop: ''
43419  });
43420  var slidesNumberEvenToRows;
43421
43422  if (params.slidesPerColumn > 1) {
43423    if (Math.floor(slidesLength / params.slidesPerColumn) === slidesLength / swiper.params.slidesPerColumn) {
43424      slidesNumberEvenToRows = slidesLength;
43425    } else {
43426      slidesNumberEvenToRows = Math.ceil(slidesLength / params.slidesPerColumn) * params.slidesPerColumn;
43427    }
43428
43429    if (params.slidesPerView !== 'auto' && params.slidesPerColumnFill === 'row') {
43430      slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, params.slidesPerView * params.slidesPerColumn);
43431    }
43432  } // Calc slides
43433
43434
43435  var slideSize;
43436  var slidesPerColumn = params.slidesPerColumn;
43437  var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;
43438  var numFullColumns = Math.floor(slidesLength / params.slidesPerColumn);
43439
43440  for (var i = 0; i < slidesLength; i += 1) {
43441    slideSize = 0;
43442    var slide = slides.eq(i);
43443
43444    if (params.slidesPerColumn > 1) {
43445      // Set slides order
43446      var newSlideOrderIndex = void 0;
43447      var column = void 0;
43448      var row = void 0;
43449
43450      if (params.slidesPerColumnFill === 'row' && params.slidesPerGroup > 1) {
43451        var groupIndex = Math.floor(i / (params.slidesPerGroup * params.slidesPerColumn));
43452        var slideIndexInGroup = i - params.slidesPerColumn * params.slidesPerGroup * groupIndex;
43453        var columnsInGroup = groupIndex === 0 ? params.slidesPerGroup : Math.min(Math.ceil((slidesLength - groupIndex * slidesPerColumn * params.slidesPerGroup) / slidesPerColumn), params.slidesPerGroup);
43454        row = Math.floor(slideIndexInGroup / columnsInGroup);
43455        column = slideIndexInGroup - row * columnsInGroup + groupIndex * params.slidesPerGroup;
43456        newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;
43457        slide.css({
43458          '-webkit-box-ordinal-group': newSlideOrderIndex,
43459          '-moz-box-ordinal-group': newSlideOrderIndex,
43460          '-ms-flex-order': newSlideOrderIndex,
43461          '-webkit-order': newSlideOrderIndex,
43462          order: newSlideOrderIndex
43463        });
43464      } else if (params.slidesPerColumnFill === 'column') {
43465        column = Math.floor(i / slidesPerColumn);
43466        row = i - column * slidesPerColumn;
43467
43468        if (column > numFullColumns || column === numFullColumns && row === slidesPerColumn - 1) {
43469          row += 1;
43470
43471          if (row >= slidesPerColumn) {
43472            row = 0;
43473            column += 1;
43474          }
43475        }
43476      } else {
43477        row = Math.floor(i / slidesPerRow);
43478        column = i - row * slidesPerRow;
43479      }
43480
43481      slide.css(getDirectionLabel('margin-top'), row !== 0 ? params.spaceBetween && params.spaceBetween + "px" : '');
43482    }
43483
43484    if (slide.css('display') === 'none') continue; // eslint-disable-line
43485
43486    if (params.slidesPerView === 'auto') {
43487      var slideStyles = getComputedStyle(slide[0]);
43488      var currentTransform = slide[0].style.transform;
43489      var currentWebKitTransform = slide[0].style.webkitTransform;
43490
43491      if (currentTransform) {
43492        slide[0].style.transform = 'none';
43493      }
43494
43495      if (currentWebKitTransform) {
43496        slide[0].style.webkitTransform = 'none';
43497      }
43498
43499      if (params.roundLengths) {
43500        slideSize = swiper.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);
43501      } else {
43502        // eslint-disable-next-line
43503        var width = getDirectionPropertyValue(slideStyles, 'width');
43504        var paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
43505        var paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
43506        var marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
43507        var marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
43508        var boxSizing = slideStyles.getPropertyValue('box-sizing');
43509
43510        if (boxSizing && boxSizing === 'border-box') {
43511          slideSize = width + marginLeft + marginRight;
43512        } else {
43513          var _slide$ = slide[0],
43514              clientWidth = _slide$.clientWidth,
43515              offsetWidth = _slide$.offsetWidth;
43516          slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth);
43517        }
43518      }
43519
43520      if (currentTransform) {
43521        slide[0].style.transform = currentTransform;
43522      }
43523
43524      if (currentWebKitTransform) {
43525        slide[0].style.webkitTransform = currentWebKitTransform;
43526      }
43527
43528      if (params.roundLengths) slideSize = Math.floor(slideSize);
43529    } else {
43530      slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
43531      if (params.roundLengths) slideSize = Math.floor(slideSize);
43532
43533      if (slides[i]) {
43534        slides[i].style[getDirectionLabel('width')] = slideSize + "px";
43535      }
43536    }
43537
43538    if (slides[i]) {
43539      slides[i].swiperSlideSize = slideSize;
43540    }
43541
43542    slidesSizesGrid.push(slideSize);
43543
43544    if (params.centeredSlides) {
43545      slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
43546      if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
43547      if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
43548      if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
43549      if (params.roundLengths) slidePosition = Math.floor(slidePosition);
43550      if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);
43551      slidesGrid.push(slidePosition);
43552    } else {
43553      if (params.roundLengths) slidePosition = Math.floor(slidePosition);
43554      if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);
43555      slidesGrid.push(slidePosition);
43556      slidePosition = slidePosition + slideSize + spaceBetween;
43557    }
43558
43559    swiper.virtualSize += slideSize + spaceBetween;
43560    prevSlideSize = slideSize;
43561    index += 1;
43562  }
43563
43564  swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
43565  var newSlidesGrid;
43566
43567  if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
43568    $wrapperEl.css({
43569      width: swiper.virtualSize + params.spaceBetween + "px"
43570    });
43571  }
43572
43573  if (params.setWrapperSize) {
43574    var _$wrapperEl$css;
43575
43576    $wrapperEl.css((_$wrapperEl$css = {}, _$wrapperEl$css[getDirectionLabel('width')] = swiper.virtualSize + params.spaceBetween + "px", _$wrapperEl$css));
43577  }
43578
43579  if (params.slidesPerColumn > 1) {
43580    var _$wrapperEl$css2;
43581
43582    swiper.virtualSize = (slideSize + params.spaceBetween) * slidesNumber
43582EvenToRows;
43583    swiper.virtualSize = Math.ceil(swiper.virtualSize / params.slidesPerColumn) - params.spaceBetween;
43584    $wrapperEl.css((_$wrapperEl$css2 = {}, _$wrapperEl$css2[getDirectionLabel('width')] = swiper.virtualSize + params.spaceBetween + "px", _$wrapperEl$css2));
43585
43586    if (params.centeredSlides) {
43587      newSlidesGrid = [];
43588
43589      for (var _i = 0; _i < snapGrid.length; _i += 1) {
43590        var slidesGridItem = snapGrid[_i];
43591        if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
43592        if (snapGrid[_i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem);
43593      }
43594
43595      snapGrid = newSlidesGrid;
43596    }
43597  } // Remove last grid elements depending on width
43598
43599
43600  if (!params.centeredSlides) {
43601    newSlidesGrid = [];
43602
43603    for (var _i2 = 0; _i2 < snapGrid.length; _i2 += 1) {
43604      var _slidesGridItem = snapGrid[_i2];
43605      if (params.roundLengths) _slidesGridItem = Math.floor(_slidesGridItem);
43606
43607      if (snapGrid[_i2] <= swiper.virtualSize - swiperSize) {
43608        newSlidesGrid.push(_slidesGridItem);
43609      }
43610    }
43611
43612    snapGrid = newSlidesGrid;
43613
43614    if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
43615      snapGrid.push(swiper.virtualSize - swiperSize);
43616    }
43617  }
43618
43619  if (snapGrid.length === 0) snapGrid = [0];
43620
43621  if (params.spaceBetween !== 0) {
43622    var _slides$filter$css;
43623
43624    var key = swiper.isHorizontal() && rtl ? 'marginLeft' : getDirectionLabel('marginRight');
43625    slides.filter(function (_, slideIndex) {
43626      if (!params.cssMode) return true;
43627
43628      if (slideIndex === slides.length - 1) {
43629        return false;
43630      }
43631
43632      return true;
43633    }).css((_slides$filter$css = {}, _slides$filter$css[key] = spaceBetween + "px", _slides$filter$css));
43634  }
43635
43636  if (params.centeredSlides && params.centeredSlidesBounds) {
43637    var allSlidesSize = 0;
43638    slidesSizesGrid.forEach(function (slideSizeValue) {
43639      allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);
43640    });
43641    allSlidesSize -= params.spaceBetween;
43642    var maxSnap = allSlidesSize - swiperSize;
43643    snapGrid = snapGrid.map(function (snap) {
43644      if (snap < 0) return -offsetBefore;
43645      if (snap > maxSnap) return maxSnap + offsetAfter;
43646      return snap;
43647    });
43648  }
43649
43650  if (params.centerInsufficientSlides) {
43651    var _allSlidesSize = 0;
43652    slidesSizesGrid.forEach(function (slideSizeValue) {
43653      _allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);
43654    });
43655    _allSlidesSize -= params.spaceBetween;
43656
43657    if (_allSlidesSize < swiperSize) {
43658      var allSlidesOffset = (swiperSize - _allSlidesSize) / 2;
43659      snapGrid.forEach(function (snap, snapIndex) {
43660        snapGrid[snapIndex] = snap - allSlidesOffset;
43661      });
43662      slidesGrid.forEach(function (snap, snapIndex) {
43663        slidesGrid[snapIndex] = snap + allSlidesOffset;
43664      });
43665    }
43666  }
43667
43668  Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["e" /* extend */])(swiper, {
43669    slides: slides,
43670    snapGrid: snapGrid,
43671    slidesGrid: slidesGrid,
43672    slidesSizesGrid: slidesSizesGrid
43673  });
43674
43675  if (slidesLength !== previousSlidesLength) {
43676    swiper.emit('slidesLengthChange');
43677  }
43678
43679  if (snapGrid.length !== previousSnapGridLength) {
43680    if (swiper.params.watchOverflow) swiper.checkOverflow();
43681    swiper.emit('snapGridLengthChange');
43682  }
43683
43684  if (slidesGrid.length !== previousSlidesGridLength) {
43685    swiper.emit('slidesGridLengthChange');
43686  }
43687
43688  if (params.watchSlidesProgress || params.watchSlidesVisibility) {
43689    swiper.updateSlidesOffset();
43690  }
43691}
43692
43693/***/ }),
43694/* 176 */
43695/***/ (function(module, __webpack_exports__, __webpack_require__) {
43696
43697"use strict";
43698/* harmony export (immutable) */ __webpack_exports__["a"] = updateAutoHeight;
43699function updateAutoHeight(speed) {
43700  var swiper = this;
43701  var activeSlides = [];
43702  var isVirtual = swiper.virtual && swiper.params.virtual.enabled;
43703  var newHeight = 0;
43704  var i;
43705
43706  if (typeof speed === 'number') {
43707    swiper.setTransition(speed);
43708  } else if (speed === true) {
43709    swiper.setTransition(swiper.params.speed);
43710  }
43711
43712  var getSlideByIndex = function getSlideByIndex(index) {
43713    if (isVirtual) {
43714      return swiper.slides.filter(function (el) {
43715        return parseInt(el.getAttribute('data-swiper-slide-index'), 10) === index;
43716      })[0];
43717    }
43718
43719    return swiper.slides.eq(index)[0];
43720  }; // Find slides currently in view
43721
43722
43723  if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
43724    if (swiper.params.centeredSlides) {
43725      swiper.visibleSlides.each(function (slide) {
43726        activeSlides.push(slide);
43727      });
43728    } else {
43729      for (i = 0;
43729 i < Math.ceil(swiper.params.slidesPerView); i += 1) {
43730        var index = swiper.activeIndex + i;
43731        if (index > swiper.slides.length && !isVirtual) break;
43732        activeSlides.push(getSlideByIndex(index));
43733      }
43734    }
43735  } else {
43736    activeSlides.push(getSlideByIndex(swiper.activeIndex));
43737  } // Find new height from highest slide in view
43738
43739
43740  for (i = 0; i < activeSlides.length; i += 1) {
43741    if (typeof activeSlides[i] !== 'undefined') {
43742      var height = activeSlides[i].offsetHeight;
43743      newHeight = height > newHeight ? height : newHeight;
43744    }
43745  } // Update Height
43746
43747
43748  if (newHeight) swiper.$wrapperEl.css('height', newHeight + "px");
43749}
43750
43751/***/ }),
43752/* 177 */
43753/***/ (function(module, __webpack_exports__, __webpack_require__) {
43754
43755"use strict";
43756/* harmony export (immutable) */ __webpack_exports__["a"] = updateSlidesOffset;
43757function updateSlidesOffset() {
43758  var swiper = this;
43759  var slides = swiper.slides;
43760
43761  for (var i = 0; i < slides.length; i += 1) {
43762    slides[i].swiperSlideOffset = swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop;
43763  }
43764}
43765
43766/***/ }),
43767/* 178 */
43768/***/ (function(module, __webpack_exports__, __webpack_require__) {
43769
43770"use strict";
43771/* harmony export (immutable) */ __webpack_exports__["a"] = updateSlidesProgress;
43772/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_dom__ = __webpack_require__(3);
43773
43774function updateSlidesProgress(translate) {
43775  if (translate === void 0) {
43776    translate = this && this.translate || 0;
43777  }
43778
43779  var swiper = this;
43780  var params = swiper.params;
43781  var slides = swiper.slides,
43782      rtl = swiper.rtlTranslate;
43783  if (slides.length === 0) return;
43784  if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();
43785  var offsetCenter = -translate;
43786  if (rtl) offsetCenter = translate; // Visible Slides
43787
43788  slides.removeClass(params.slideVisibleClass);
43789  swiper.visibleSlidesIndexes = [];
43790  swiper.visibleSlides = [];
43791
43792  for (var i = 0; i < slides.length; i += 1) {
43793    var slide = slides[i];
43794    var slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slide.swiperSlideOffset) / (slide.swiperSlideSize + params.spaceBetween);
43795
43796    if (params.watchSlidesVisibility || params.centeredSlides && params.autoHeight) {
43797      var slideBefore = -(offsetCenter - slide.swiperSlideOffset);
43798      var slideAfter = slideBefore + swiper.slidesSizesGrid[i];
43799      var isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper.size || slideBefore <= 0 && slideAfter >= swiper.size;
43800
43801      if (isVisible) {
43802        swiper.visibleSlides.push(slide);
43803        swiper.visibleSlidesIndexes.push(i);
43804        slides.eq(i).addClass(params.slideVisibleClass);
43805      }
43806    }
43807
43808    slide.progress = rtl ? -slideProgress : slideProgress;
43809  }
43810
43811  swiper.visibleSlides = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(swiper.visibleSlides);
43812}
43813
43814/***/ }),
43815/* 179 */
43816/***/ (function(module, __webpack_exports__, __webpack_require__) {
43817
43818"use strict";
43819/* harmony export (immutable) */ __webpack_exports__["a"] = updateProgress;
43820/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_utils__ = __webpack_require__(1);
43821
43822function updateProgress(translate) {
43823  var swiper = this;
43824
43825  if (typeof translate === 'undefined') {
43826    var multiplier = swiper.rtlTranslate ? -1 : 1; // eslint-disable-next-line
43827
43828    translate = swiper && swiper.translate && swiper.translate * multiplier || 0;
43829  }
43830
43831  var params = swiper.params;
43832  var translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
43833  var progress = swiper.progress,
43834      isBeginning = swiper.isBeginning,
43835      isEnd = swiper.isEnd;
43836  var wasBeginning = isBeginning;
43837  var wasEnd = isEnd;
43838
43839  if (translatesDiff === 0) {
43840    progress = 0;
43841    isBeginning = true;
43842    isEnd = true;
43843  } else {
43844    progress = (translate - swiper.minTranslate()) / translatesDiff;
43845    isBeginning = progress <= 0;
43846    isEnd = progress >= 1;
43847  }
43848
43849  Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["e" /* extend */])(swiper, {
43850    progress: progress,
43851    isBeginning: isBeginning,
43852    isEnd: isEnd
43853  });
43854  if (params.watchSlidesProgress || params.watchSlidesVisibility || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate);
43855
43856  if (isBeginning && !wasBeginning) {
43857    swiper.emit('reachBeginning toEdge');
43858  }
43859
43860  if (isEnd && !wasEnd) {
43861    swiper.emit('reachEnd toEdge');
43862  }
43863
43864  if (wasBeginning && !isBeginning || wasEnd && !isEnd) {
43865    swiper.emit('fromEdge');
43866  }
43867
43868  swiper.emit('progress', progress);
43869}
43870
43871/***/ }),
43872/* 180 */
43873/***/ (function(module, __webpack_exports__, __webpack_require__) {
43874
43875"use strict";
43876/* harmony export (immutable) */ __webpack_exports__["a"] = updateSlidesClasses;
43877function updateSlidesClasses() {
43878  var swiper = this;
43879  var slides = swiper.slides,
43880      params = swiper.params,
43881      $wrapperEl = swiper.$wrapperEl,
43882      activeIndex = swiper.activeIndex,
43883      realIndex = swiper.realIndex;
43884  var isVirtual = swiper.virtual && params.virtual.enabled;
43885  slides.removeClass(params.slideActiveClass + " " + params.slideNextClass + " " + params.slidePrevClass + " " + params.slideDuplicateActiveClass + " " + params.slideDuplicateNextClass + " " + params.slideDuplicatePrevClass);
43886  var activeSlide;
43887
43888  if (isVirtual) {
43889    activeSlide = swiper.$wrapperEl.find("." + params.slideClass + "[data-swiper-slide-index=\"" + activeIndex + "\"]");
43890  } else {
43891    activeSlide = slides.eq(activeIndex);
43892  } // Active classes
43893
43894
43895  activeSlide.addClass(params.slideActiveClass);
43896
43897  if (params.loop) {
43898    // Duplicate to all looped slides
43899    if (activeSlide.hasClass(params.slideDuplicateClass)) {
43900      $wrapperEl.children("." + params.slideClass + ":not(." + params.slideDuplicateClass + ")[data-swiper-slide-index=\"" + realIndex + "\"]").addClass(params.slideDuplicateActiveClass);
43901    } else {
43902      $wrapperEl.children("." + params.slideClass + "." + params.slideDuplicateClass + "[data-swiper-slide-index=\"" + realIndex + "\"]").addClass(params.slideDuplicateActiveClass);
43903    }
43904  } // Next Slide
43905
43906
43907  var nextSlide = activeSlide.nextAll("." + params.slideClass).eq(0).addClass(params.slideNextClass);
43908
43909  if (params.loop && nextSlide.length === 0) {
43910    nextSlide = slides.eq(0);
43911    nextSlide.addClass(params.slideNextClass);
43912  } // Prev Slide
43913
43914
43915  var prevSlide = activeSlide.prevAll("." + params.slideClass).eq(0).addClass(params.slidePrevClass);
43916
43917  if (params.loop && prevSlide.length === 0) {
43918    prevSlide = slides.eq(-1);
43919    prevSlide.addClass(params.slidePrevClass);
43920  }
43921
43922  if (params.loop) {
43923    // Duplicate to all looped slides
43924    if (nextSlide.hasClass(params.slideDuplicateClass)) {
43925      $wrapperEl.children("." + params.slideClass + ":not(." + params.slideDuplicateClass + ")[data-swiper-slide-index=\"" + nextSlide.attr('data-swiper-slide-index') + "\"]").addClass(params.slideDuplicateNextClass);
43926    } else {
43927      $wrapperEl.children("." + params.slideClass + "." + params.slideDuplicateClass + "[data-swiper-slide-index=\"" + nextSlide.attr('data-swiper-slide-index') + "\"]").addClass(params.slideDuplicateNextClass);
43928    }
43929
43930    if (prevSlide.hasClass(params.slideDuplicateClass)) {
43931      $wrapperEl.children("." + params.slideClass + ":not(." + params.slideDuplicateClass + ")[data-swiper-slide-index=\"" + prevSlide.attr('data-swiper-slide-index') + "\"]").addClass(params.slideDuplicatePrevClass);
43932    } else {
43933      $wrapperEl.children("." + params.slideClass + "." + params.slideDuplicateClass + "[data-swiper-slide-index=\"" + prevSlide.attr('data-swiper-slide-index') + "\"]").addClass(params.slideDuplicatePrevClass);
43934    }
43935  }
43936
43937  swiper.emitSlidesClasses();
43938}
43939
43940/***/ }),
43941/* 181 */
43942/***/ (function(module, __webpack_exports__, __webpack_require__) {
43943
43944"use strict";
43945/* harmony export (immutable) */ __webpack_exports__["a"] = updateActiveIndex;
43946/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_utils__ = __webpack_require__(1);
43947
43948function updateActiveIndex(newActiveIndex) {
43949  var swiper = this;
43950  var translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
43951  var slidesGrid = swiper.slidesGrid,
43952      snapGrid = swiper.snapGrid,
43953      params = swiper.params,
43954      previousIndex = swiper.activeIndex,
43955      previousRealIndex = swiper.realIndex,
43956      previousSnapIndex = swiper.snapIndex;
43957  var activeIndex = newActiveIndex;
43958  var snapIndex;
43959
43960  if (typeof activeIndex === 'undefined') {
43961    for (var i = 0; i < slidesGrid.length; i += 1) {
43962      if (typeof slidesGrid[i + 1] !== 'undefined') {
43963        if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) {
43964          activeIndex = i;
43965        } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {
43966          activeIndex = i + 1;
43967        }
43968      } else if (translate >= slidesGrid[i]) {
43969        activeIndex = i;
43970      }
43971    } // Normalize slideIndex
43972
43973
43974    if (params.normalizeSlideIndex) {
43975      if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
43976    }
43977  }
43978
43979  if (snapGrid.indexOf(translate) >= 0) {
43980    snapIndex = snapGrid.indexOf(translate);
43981  } else {
43982    var skip = Math.min(params.slidesPerGroupSkip, activeIndex);
43983    snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
43984  }
43985
43986  if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
43987
43988  if (activeIndex === previousIndex) {
43989    if (snapIndex !== previousSnapIndex) {
43990      swiper.snapIndex = snapIndex;
43991      swiper.emit('snapIndexChange');
43992    }
43993
43994    return;
43995  } // Get real index
43996
43997
43998  var realIndex = parseInt(swiper.slides.eq(activeIndex).attr('data-swiper-slide-index') || activeIndex, 10);
43999  Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["e" /* extend */])(swiper, {
44000    snapIndex: snapIndex,
44001    realIndex: realIndex,
44002    previousIndex: previousIndex,
44003    activeIndex: activeIndex
44004  });
44005  swiper.emit('activeIndexChange');
44006  swiper.emit('snapIndexChange');
44007
44008  if (previousRealIndex !== realIndex) {
44009    swiper.emit('realIndexChange');
44010  }
44011
44012  if (swiper.initialized || swiper.params.runCallbacksOnInit) {
44013    swiper.emit('slideChange');
44014  }
44015}
44016
44017/***/ }),
44018/* 182 */
44019/***/ (function(module, __webpack_exports__, __webpack_require__) {
44020
44021"use strict";
44022/* harmony export (immutable) */ __webpack_exports__["a"] = updateClickedSlide;
44023/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_dom__ = __webpack_require__(3);
44024
44025function updateClickedSlide(e) {
44026  var swiper = this;
44027  var params = swiper.params;
44028  var slide = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(e.target).closest("." + params.slideClass)[0];
44029  var slideFound = false;
44030  var slideIndex;
44031
44032  if (slide) {
44033    for (var i = 0; i < swiper.slides.length; i += 1) {
44034      if (swiper.slides[i] === slide) {
44035        slideFound = true;
44036        slideIndex = i;
44037        break;
44038      }
44039    }
44040  }
44041
44042  if (slide && slideFound) {
44043    swiper.clickedSlide = slide;
44044
44045    if (swiper.virtual && swiper.params.virtual.enabled) {
44046      swiper.clickedIndex = parseInt(Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(slide).attr('data-swiper-slide-index'), 10);
44047    } else {
44048      swiper.clickedIndex = slideIndex;
44049    }
44050  } else {
44051    swiper.clickedSlide = undefined;
44052    swiper.clickedIndex = undefined;
44053    return;
44054  }
44055
44056  if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {
44057    swiper.slideToClickedSlide();
44058  }
44059}
44060
44061/***/ }),
44062/* 183 */
44063/***/ (function(module, __webpack_exports__, __webpack_require__) {
44064
44065"use strict";
44066/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__getTranslate__ = __webpack_require__(184);
44067/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__setTranslate__ = __webpack_require__(185);
44068/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__minTranslate__ = __webpack_require__(186);
44069/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__maxTranslate__ = __webpack_require__(187);
44070/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__translateTo__ = __webpack_require__(188);
44071
44072
44073
44074
44075
44076/* harmony default export */ __webpack_exports__["a"] = ({
44077  getTranslate: __WEBPACK_IMPORTED_MODULE_0__getTranslate__["a" /* default */],
44078  setTranslate: __WEBPACK_IMPORTED_MODULE_1__setTranslate__["a" /* default */],
44079  minTranslate: __WEBPACK_IMPORTED_MODULE_2__minTranslate__["a" /* default */],
44080  maxTranslate: __WEBPACK_IMPORTED_MODULE_3__maxTranslate__["a" /* default */],
44081  translateTo: __WEBPACK_IMPORTED_MODULE_4__translateTo__["a" /* default */]
44082});
44083
44084/***/ }),
44085/* 184 */
44086/***/ (function(module, __webpack_exports__, __webpack_require__) {
44087
44088"use strict";
44089/* harmony export (immutable) */ __webpack_exports__["a"] = getSwiperTranslate;
44090/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_utils__ = __webpack_require__(1);
44091
44092function getSwiperTranslate(axis) {
44093  if (axis === void 0) {
44094    axis = this.isHorizontal() ? 'x' : 'y';
44095  }
44096
44097  var swiper = this;
44098  var params = swiper.params,
44099      rtl = swiper.rtlTranslate,
44100      translate = swiper.translate,
44101      $wrapperEl = swiper.$wrapperEl;
44102
44103  if (params.virtualTranslate) {
44104    return rtl ? -translate : translate;
44105  }
44106
44107  if (params.cssMode) {
44108    return translate;
44109  }
44110
44111  var currentTranslate = Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["f" /* getTranslate */])($wrapperEl[0], axis);
44112  if (rtl) currentTranslate = -currentTranslate;
44113  return currentTranslate || 0;
44114}
44115
44116/***/ }),
44117/* 185 */
44118/***/ (function(module, __webpack_exports__, __webpack_require__) {
44119
44120"use strict";
44121/* harmony export (immutable) */ __webpack_exports__["a"] = setTranslate;
44122function setTranslate(translate, byController) {
44123  var swiper = this;
44124  var rtl = swiper.rtlTranslate,
44125      params = swiper.params,
44126      $wrapperEl = swiper.$wrapperEl,
44127      wrapperEl = swiper.wrapperEl,
44128      progress = swiper.progress;
44129  var x = 0;
44130  var y = 0;
44131  var z = 0;
44132
44133  if (swiper.isHorizontal()) {
44134    x = rtl ? -translate : translate;
44135  } else {
44136    y = translate;
44137  }
44138
44139  if (params.roundLengths) {
44140    x = Math.floor(x);
44141    y = Math.floor(y);
44142  }
44143
44144  if (params.cssMode) {
44145    wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
44146  } else if (!params.virtualTranslate) {
44147    $wrapperEl.transform("translate3d(" + x + "px, " + y + "px, " + z + "px)");
44148  }
44149
44150  swiper.previousTranslate = swiper.translate;
44151  swiper.translate = swiper.isHorizontal() ? x : y; // Check if we need to update progress
44152
44153  var newProgress;
44154  var translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
44155
44156  if (translatesDiff === 0) {
44157    newProgress = 0;
44158  } else {
44159    newProgress = (translate - swiper.minTranslate()) / translatesDiff;
44160  }
44161
44162  if (newProgress !== progress) {
44163    swiper.updateProgress(translate);
44164  }
44165
44166  swiper.emit('setTranslate', swiper.translate, byController);
44167}
44168
44169/***/ }),
44170/* 186 */
44171/***/ (function(module, __webpack_exports__, __webpack_require__) {
44172
44173"use strict";
44174/* harmony export (immutable) */ __webpack_exports__["a"] = minTranslate;
44175function minTranslate() {
44176  return -this.snapGrid[0];
44177}
44178
44179/***/ }),
44180/* 187 */
44181/***/ (function(module, __webpack_exports__, __webpack_require__) {
44182
44183"use strict";
44184/* harmony export (immutable) */ __webpack_exports__["a"] = maxTranslate;
44185function maxTranslate() {
44186  return -this.snapGrid[this.snapGrid.length - 1];
44187}
44188
44189/***/ }),
44190/* 188 */
44191/***/ (function(module, __webpack_exports__, __webpack_require__) {
44192
44193"use strict";
44194/* harmony export (immutable) */ __webpack_exports__["a"] = translateTo;
44195function translateTo(translate, speed, runCallbacks, translateBounds, internal) {
44196  if (translate === void 0) {
44197    translate = 0;
44198  }
44199
44200  if (speed === void 0) {
44201    speed = this.params.speed;
44202  }
44203
44204  if (runCallbacks === void 0) {
44205    runCallbacks = true;
44206  }
44207
44208  if (translateBounds === void 0) {
44209    translateBounds = true;
44210  }
44211
44212  var swiper = this;
44213  var params = swiper.params,
44214      wrapperEl = swiper.wrapperEl;
44215
44216  if (swiper.animating && params.preventInteractionOnTransition) {
44217    return false;
44218  }
44219
44220  var minTranslate = swiper.minTranslate();
44221  var maxTranslate = swiper.maxTranslate();
44222  var newTranslate;
44223  if (translateBounds && translate > minTranslate) newTranslate = minTranslate;else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;else newTranslate = translate; // Update progress
44224
44225  swiper.updateProgress(newTranslate);
44226
44227  if (params.cssMode) {
44228    var isH = swiper.isHorizontal();
44229
44230    if (speed === 0) {
44231      wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
44232    } else {
44233      // eslint-disable-next-line
44234      if (wrapperEl.scrollTo) {
44235        var _wrapperEl$scrollTo;
44236
44237        wrapperEl.scrollTo((_wrapperEl$scrollTo = {}, _wrapperEl$scrollTo[isH ? 'left' : 'top'] = -newTranslate, _wrapperEl$scrollTo.behavior = 'smooth', _wrapperEl$scrollTo));
44238      } else {
44239        wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
44240      }
44241    }
44242
44243    return true;
44244  }
44245
44246  if (speed === 0) {
44247    swiper.setTransition(0);
44248    swiper.setTranslate(newTranslate);
44249
44250    if (runCallbacks) {
44251      swiper.emit('beforeTransitionStart', speed, internal);
44252      swiper.emit('transitionEnd');
44253    }
44254  } else {
44255    swiper.setTransition(speed);
44256    swiper.setTranslate(newTranslate);
44257
44258    if (runCallbacks) {
44259      swiper.emit('beforeTransitionStart', speed, internal);
44260      swiper.emit('transitionStart');
44261    }
44262
44263    if (!swiper.animating) {
44264      swiper.animating = true;
44265
44266      if (!swiper.onTranslateToWrapperTransitionEnd) {
44267        swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {
44268          if (!swiper || swiper.destroyed) return;
44269          if (e.target !== this) return;
44270          swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
44271          swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onTranslateToWrapperTransitionEnd);
44272          swiper.onTranslateToWrapperTransitionEnd = null;
44273          delete swiper.onTranslateToWrapperTransitionEnd;
44274
44275          if (runCallbacks) {
44276            swiper.emit('transitionEnd');
44277          }
44278        };
44279      }
44280
44281      swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
44282      swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onTranslateToWrapperTransitionEnd);
44283    }
44284  }
44285
44286  return true;
44287}
44288
44289/***/ }),
44290/* 189 */
44291/***/ (function(module, __webpack_exports__, __webpack_require__) {
44292
44293"use strict";
44294/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__setTransition__ = __webpack_require__(190);
44295/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__transitionStart__ = __webpack_require__(191);
44296/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__transitionEnd__ = __webpack_require__(192);
44297
44298
44299
44300/* harmony default export */ __webpack_exports__["a"] = ({
44301  setTransition: __WEBPACK_IMPORTED_MODULE_0__setTransition__["a" /* default */],
44302  transitionStart: __WEBPACK_IMPORTED_MODULE_1__transitionStart__["a" /* default */],
44303  transitionEnd: __WEBPACK_IMPORTED_MODULE_2__transitionEnd__["a" /* default */]
44304});
44305
44306/***/ }),
44307/* 190 */
44308/***/ (function(module, __webpack_exports__, __webpack_require__) {
44309
44310"use strict";
44311/* harmony export (immutable) */ __webpack_exports__["a"] = setTransition;
44312function setTransition(duration, byController) {
44313  var swiper = this;
44314
44315  if (!swiper.params.cssMode) {
44316    swiper.$wrapperEl.transition(duration);
44317  }
44318
44319  swiper.emit('setTransition', duration, byController);
44320}
44321
44322/***/ }),
44323/* 191 */
44324/***/ (function(module, __webpack_exports__, __webpack_require__) {
44325
44326"use strict";
44327/* harmony export (immutable) */ __webpack_exports__["a"] = transitionStart;
44328function transitionStart(runCallbacks, direction) {
44329  if (runCallbacks === void 0) {
44330    runCallbacks = true;
44331  }
44332
44333  var swiper = this;
44334  var activeIndex = swiper.activeIndex,
44335      params = swiper.params,
44336      previousIndex = swiper.previousIndex;
44337  if (params.cssMode) return;
44338
44339  if (params.autoHeight) {
44340    swiper.updateAutoHeight();
44341  }
44342
44343  var dir = direction;
44344
44345  if (!dir) {
44346    if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset';
44347  }
44348
44349  swiper.emit('transitionStart');
44350
44351  if (runCallbacks && activeIndex !== previousIndex) {
44352    if (dir === 'reset') {
44353      swiper.emit('slideResetTransitionStart');
44354      return;
44355    }
44356
44357    swiper.emit('slideChangeTransitionStart');
44358
44359    if (dir === 'next') {
44360      swiper.emit('slideNextTransitionStart');
44361    } else {
44362      swiper.emit('slidePrevTransitionStart');
44363    }
44364  }
44365}
44366
44367/***/ }),
44368/* 192 */
44369/***/ (function(module, __webpack_exports__, __webpack_require__) {
44370
44371"use strict";
44372/* harmony export (immutable) */ __webpack_exports__["a"] = transitionEnd;
44373function transitionEnd(runCallbacks, direction) {
44374  if (runCallbacks === void 0) {
44375    runCallbacks = true;
44376  }
44377
44378  var swiper = this;
44379  var activeIndex = swiper.activeIndex,
44380      previousIndex = swiper.previousIndex,
44381      params = swiper.params;
44382  swiper.animating = false;
44383  if (params.cssMode) return;
44384  swiper.setTransition(0);
44385  var dir = direction;
44386
44387  if (!dir) {
44388    if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset';
44389  }
44390
44391  swiper.emit('transitionEnd');
44392
44393  if (runCallbacks && activeIndex !== previousIndex) {
44394    if (dir === 'reset') {
44395      swiper.emit('slideResetTransitionEnd');
44396      return;
44397    }
44398
44399    swiper.emit('slideChangeTransitionEnd');
44400
44401    if (dir === 'next') {
44402      swiper.emit('slideNextTransitionEnd');
44403    } else {
44404      swiper.emit('slidePrevTransitionEnd');
44405    }
44406  }
44407}
44408
44409/***/ }),
44410/* 193 */
44411/***/ (function(module, __webpack_exports__, __webpack_require__) {
44412
44413"use strict";
44414/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__slideTo__ = __webpack_require__(194);
44415/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__slideToLoop__ = __webpack_require__(195);
44416/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__slideNext__ = __webpack_require__(196);
44417/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__slidePrev__ = __webpack_require__(197);
44418/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__slideReset__ = __webpack_require__(198);
44419/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__slideToClosest__ = __webpack_require__(199);
44420/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__slideToClickedSlide__ = __webpack_require__(200);
44421
44422
44423
44424
44425
44426
44427
44428/* harmony default export */ __webpack_exports__["a"] = ({
44429  slideTo: __WEBPACK_IMPORTED_MODULE_0__slideTo__["a" /* default */],
44430  slideToLoop: __WEBPACK_IMPORTED_MODULE_1__slideToLoop__["a" /* default */],
44431  slideNext: __WEBPACK_IMPORTED_MODULE_2__slideNext__["a" /* default */],
44432  slidePrev: __WEBPACK_IMPORTED_MODULE_3__slidePrev__["a" /* default */],
44433  slideReset: __WEBPACK_IMPORTED_MODULE_4__slideReset__["a" /* default */],
44434  slideToClosest: __WEBPACK_IMPORTED_MODULE_5__slideToClosest__["a" /* default */],
44435  slideToClickedSlide: __WEBPACK_IMPORTED_MODULE_6__slideToClickedSlide__["a" /* default */]
44436});
44437
44438/***/ }),
44439/* 194 */
44440/***/ (function(module, __webpack_exports__, __webpack_require__) {
44441
44442"use strict";
44443/* harmony export (immutable) */ __webpack_exports__["a"] = slideTo;
44444function slideTo(index, speed, runCallbacks, internal, initial) {
44445  if (index === void 0) {
44446    index = 0;
44447  }
44448
44449  if (speed === void 0) {
44450    speed = this.params.speed;
44451  }
44452
44453  if (runCallbacks === void 0) {
44454    runCallbacks = true;
44455  }
44456
44457  if (typeof index !== 'number' && typeof index !== 'string') {
44458    throw new Error("The 'index' argument cannot have type other than 'number' or 'string'. [" + typeof index + "] given.");
44459  }
44460
44461  if (typeof index === 'string') {
44462    /**
44463     * The `index` argument converted from `string` to `number`.
44464     * @type {number}
44465     */
44466    var indexAsNumber = parseInt(index, 10);
44467    /**
44468     * Determines whether the `index` argument is a valid `number`
44469     * after being converted from the `string` type.
44470     * @type {boolean}
44471     */
44472
44473    var isValidNumber = isFinite(indexAsNumber);
44474
44475    if (!isValidNumber) {
44476      throw new Error("The passed-in 'index' (string) couldn't be converted to 'number'. [" + index + "] given.");
44477    } // Knowing that the converted `index` is a valid number,
44478    // we can update the original argument's value.
44479
44480
44481    index = indexAsNumber;
44482  }
44483
44484  var swiper = this;
44485  var slideIndex = index;
44486  if (slideIndex < 0) slideIndex = 0;
44487  var params = swiper.params,
44488      snapGrid = swiper.snapGrid,
44489      slidesGrid = swiper.slidesGrid,
44490      previousIndex = swiper.previousIndex,
44491      activeIndex = swiper.activeIndex,
44492      rtl = swiper.rtlTranslate,
44493      wrapperEl = swiper.wrapperEl,
44494      enabled = swiper.enabled;
44495
44496  if (swiper.animating && params.preventInteractionOnTransition || !enabled && !internal && !initial) {
44497    return false;
44498  }
44499
44500  var skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
44501  var snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
44502  if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
44503
44504  if ((activeIndex || params.initialSlide || 0) === (previousIndex || 0) && runCallbacks) {
44505    swiper.emit('beforeSlideChangeStart');
44506  }
44507
44508  var translate = -snapGrid[snapIndex]; // Update progress
44509
44510  swiper.updateProgress(translate); // Normalize slideIndex
44511
44512  if (params.normalizeSlideIndex) {
44513    for (var i = 0; i < slidesGrid.length; i += 1) {
44514      var normalizedTranslate = -Math.floor(translate * 100);
44515      var normalizedGird = Math.floor(slidesGrid[i] * 100);
44516      var normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
44517
44518      if (typeof slidesGrid[i + 1] !== 'undefined') {
44519        if (normalizedTranslate >= normalizedGird && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGird) / 2) {
44520          slideIndex = i;
44521        } else if (normalizedTranslate >= normalizedGird && normalizedTranslate < normalizedGridNext) {
44522          slideIndex = i + 1;
44523        }
44524      } else if (normalizedTranslate >= normalizedGird) {
44525        slideIndex = i;
44526      }
44527    }
44528  } // Directions locks
44529
44530
44531  if (swiper.initialized && slideIndex !== activeIndex) {
44532    if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) {
44533      return false;
44534    }
44535
44536    if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
44537      if ((activeIndex || 0) !== slideIndex) return false;
44538    }
44539  }
44540
44541  var direction;
44542  if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset'; // Update Index
44543
44544  if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {
44545    swiper.updateActiveIndex(slideIndex); // Update Height
44546
44547    if (params.autoHeight) {
44548      swiper.updateAutoHeight();
44549    }
44550
44551    swiper.updateSlidesClasses();
44552
44553    if (params.effect !== 'slide') {
44554      swiper.setTranslate(translate);
44555    }
44556
44557    if (direction !== 'reset') {
44558      swiper.transitionStart(runCallbacks, direction);
44559      swiper.transitionEnd(runCallbacks, direction);
44560    }
44561
44562    return false;
44563  }
44564
44565  if (params.cssMode) {
44566    var isH = swiper.isHorizontal();
44567    var t = -translate;
44568
44569    if (rtl) {
44570      t = wrapperEl.scrollWidth - wrapperEl.offsetWidth - t;
44571    }
44572
44573    if (speed === 0) {
44574      wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
44575    } else {
44576      // eslint-disable-next-line
44577      if (wrapperEl.scrollTo) {
44578        var _wrapperEl$scrollTo;
44579
44580        wrapperEl.scrollTo((_wrapperEl$scrollTo = {}, _wrapperEl$scrollTo[isH ? 'left' : 'top'] = t, _wrapperEl$scrollTo.behavior = 'smooth', _wrapperEl$scrollTo));
44581      } else {
44582        wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
44583      }
44584    }
44585
44586    return true;
44587  }
44588
44589  if (speed === 0) {
44590    swiper.setTransition(0);
44591    swiper.setTranslate(translate);
44592    swiper.updateActiveIndex(slideIndex);
44593    swiper.updateSlidesClasses();
44594    swiper.emit('beforeTransitionStart', speed, internal);
44595    swiper.transitionStart(runCallbacks, direction);
44596    swiper.transitionEnd(runCallbacks, direction);
44597  } else {
44598    swiper.setTransition(speed);
44599    swiper.setTranslate(translate);
44600    swiper.updateActiveIndex(slideIndex);
44601    swiper.updateSlidesClasses();
44602    swiper.emit('beforeTransitionStart', speed, internal);
44603    swiper.transitionStart(runCallbacks, direction);
44604
44605    if (!swiper.animating) {
44606      swiper.animating = true;
44607
44608      if (!swiper.onSlideToWrapperTransitionEnd) {
44609        swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
44610          if (!swiper || swiper.destroyed) return;
44611          if (e.target !== this) return;
44612          swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
44613          swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);
44614          swiper.onSlideToWrapperTransitionEnd = null;
44615          delete swiper.onSlideToWrapperTransitionEnd;
44616          swiper.transitionEnd(runCallbacks, direction);
44617        };
44618      }
44619
44620      swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
44621      swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);
44622    }
44623  }
44624
44625  return true;
44626}
44627
44628/***/ }),
44629/* 195 */
44630/***/ (function(module, __webpack_exports__, __webpack_require__) {
44631
44632"use strict";
44633/* harmony export (immutable) */ __webpack_exports__["a"] = slideToLoop;
44634function slideToLoop(index, speed, runCallbacks, internal) {
44635  if (index === void 0) {
44636    index = 0;
44637  }
44638
44639  if (speed === void 0) {
44640    speed = this.params.speed;
44641  }
44642
44643  if (runCallbacks === void 0) {
44644    runCallbacks = true;
44645  }
44646
44647  var swiper = this;
44648  var newIndex = index;
44649
44650  if (swiper.params.loop) {
44651    newIndex += swiper.loopedSlides;
44652  }
44653
44654  return swiper.slideTo(newIndex, speed, runCallbacks, internal);
44655}
44656
44657/***/ }),
44658/* 196 */
44659/***/ (function(module, __webpack_exports__, __webpack_require__) {
44660
44661"use strict";
44662/* harmony export (immutable) */ __webpack_exports__["a"] = slideNext;
44663/* eslint no-unused-vars: "off" */
44664function slideNext(speed, runCallbacks, internal) {
44665  if (speed === void 0) {
44666    speed = this.params.speed;
44667  }
44668
44669  if (runCallbacks === void 0) {
44670    runCallbacks = true;
44671  }
44672
44673  var swiper = this;
44674  var params = swiper.params,
44675      animating = swiper.animating,
44676      enabled = swiper.enabled;
44677  if (!enabled) return swiper;
44678  var increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup;
44679
44680  if (params.loop) {
44681    if (animating && params.loopPreventsSlide) return false;
44682    swiper.loopFix(); // eslint-disable-next-line
44683
44684    swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
44685  }
44686
44687  return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
44688}
44689
44690/***/ }),
44691/* 197 */
44692/***/ (function(module, __webpack_exports__, __webpack_require__) {
44693
44694"use strict";
44695/* harmony export (immutable) */ __webpack_exports__["a"] = slidePrev;
44696/* eslint no-unused-vars: "off" */
44697function slidePrev(speed, runCallbacks, internal) {
44698  if (speed === void 0) {
44699    speed = this.params.speed;
44700  }
44701
44702  if (runCallbacks === void 0) {
44703    runCallbacks = true;
44704  }
44705
44706  var swiper = this;
44707  var params = swiper.params,
44708      animating = swiper.animating,
44709      snapGrid = swiper.snapGrid,
44710      slidesGrid = swiper.slidesGrid,
44711      rtlTranslate = swiper.rtlTranslate,
44712      enabled = swiper.enabled;
44713  if (!enabled) return swiper;
44714
44715  if (params.loop) {
44716    if (animating && params.loopPreventsSlide) return false;
44717    swiper.loopFix(); // eslint-disable-next-line
44718
44719    swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
44720  }
44721
44722  var translate = rtlTranslate ? swiper.translate : -swiper.translate;
44723
44724  function normalize(val) {
44725    if (val < 0) return -Math.floor(Math.abs(val));
44726    return Math.floor(val);
44727  }
44728
44729  var normalizedTranslate = normalize(translate);
44730  var normalizedSnapGrid = snapGrid.map(function (val) {
44731    return normalize(val);
44732  });
44733  var prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
44734
44735  if (typeof prevSnap === 'undefined' && params.cssMode) {
44736    snapGrid.forEach(function (snap) {
44737      if (!prevSnap && normalizedTranslate >= snap) prevSnap = snap;
44738    });
44739  }
44740
44741  var prevIndex;
44742
44743  if (typeof prevSnap !== 'undefined') {
44744    prevIndex = slidesGrid.indexOf(prevSnap);
44745    if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;
44746  }
44747
44748  return swiper.slideTo(prevIndex, speed, runCallbacks, internal);
44749}
44750
44751/***/ }),
44752/* 198 */
44753/***/ (function(module, __webpack_exports__, __webpack_require__) {
44754
44755"use strict";
44756/* harmony export (immutable) */ __webpack_exports__["a"] = slideReset;
44757/* eslint no-unused-vars: "off" */
44758function slideReset(speed, runCallbacks, internal) {
44759  if (speed === void 0) {
44760    speed = this.params.speed;
44761  }
44762
44763  if (runCallbacks === void 0) {
44764    runCallbacks = true;
44765  }
44766
44767  var swiper = this;
44768  return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
44769}
44770
44771/***/ }),
44772/* 199 */
44773/***/ (function(module, __webpack_exports__, __webpack_require__) {
44774
44775"use strict";
44776/* harmony export (immutable) */ __webpack_exports__["a"] = slideToClosest;
44777/* eslint no-unused-vars: "off" */
44778function slideToClosest(speed, runCallbacks, internal, threshold) {
44779  if (speed === void 0) {
44780    speed = this.params.speed;
44781  }
44782
44783  if (runCallbacks === void 0) {
44784    runCallbacks = true;
44785  }
44786
44787  if (threshold === void 0) {
44788    threshold = 0.5;
44789  }
44790
44791  var swiper = this;
44792  var index = swiper.activeIndex;
44793  var skip = Math.min(swiper.params.slidesPerGroupSkip, index);
44794  var snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
44795  var translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
44796
44797  if (translate >= swiper.snapGrid[snapIndex]) {
44798    // The current translate is on or after the current snap index, so the choice
44799    // is between the current index and the one after it.
44800    var currentSnap = swiper.snapGrid[snapIndex];
44801    var nextSnap = swiper.snapGrid[snapIndex + 1];
44802
44803    if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {
44804      index += swiper.params.slidesPerGroup;
44805    }
44806  } else {
44807    // The current translate is before the current snap index, so the choice
44808    // is between the current index and the one before it.
44809    var prevSnap = swiper.snapGrid[snapIndex - 1];
44810    var _currentSnap = swiper.snapGrid[snapIndex];
44811
44812    if (translate - prevSnap <= (_currentSnap - prevSnap) * threshold) {
44813      index -= swiper.params.slidesPerGroup;
44814    }
44815  }
44816
44817  index = Math.max(index, 0);
44818  index = Math.min(index, swiper.slidesGrid.length - 1);
44819  return swiper.slideTo(index, speed, runCallbacks, internal);
44820}
44821
44822/***/ }),
44823/* 200 */
44824/***/ (function(module, __webpack_exports__, __webpack_require__) {
44825
44826"use strict";
44827/* harmony export (immutable) */ __webpack_exports__["a"] = slideToClickedSlide;
44828/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_dom__ = __webpack_require__(3);
44829/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
44830
44831
44832function slideToClickedSlide() {
44833  var swiper = this;
44834  var params = swiper.params,
44835      $wrapperEl = swiper.$wrapperEl;
44836  var slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
44837  var slideToIndex = swiper.clickedIndex;
44838  var realIndex;
44839
44840  if (params.loop) {
44841    if (swiper.animating) return;
44842    realIndex = parseInt(Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(swiper.clickedSlide).attr('data-swiper-slide-index'), 10);
44843
44844    if (params.centeredSlides) {
44845      if (slideToIndex < swiper.loopedSlides - slidesPerView / 2 || slideToIndex > swiper.slides.length - swiper.loopedSlides + slidesPerView / 2) {
44846        swiper.loopFix();
44847        slideToIndex = $wrapperEl.children("." + params.slideClass + "[data-swiper-slide-index=\"" + realIndex + "\"]:not(." + params.slideDuplicateClass + ")").eq(0).index();
44848        Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["h" /* nextTick */])(function () {
44849          swiper.slideTo(slideToIndex);
44850        });
44851      } else {
44852        swiper.slideTo(slideToIndex);
44853      }
44854    } else if (slideToIndex > swiper.slides.length - slidesPerView) {
44855      swiper.loopFix();
44856      slideToIndex = $wrapperEl.children("." + params.slideClass + "[data-swiper-slide-index=\"" + realIndex + "\"]:not(." + params.slideDuplicateClass + ")").eq(0).index();
44857      Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["h" /* nextTick */])(function () {
44858        swiper.slideTo(slideToIndex);
44859      });
44860    } else {
44861      swiper.slideTo(slideToIndex);
44862    }
44863  } else {
44864    swiper.slideTo(slideToIndex);
44865  }
44866}
44867
44868/***/ }),
44869/* 201 */
44870/***/ (function(module, __webpack_exports__, __webpack_require__) {
44871
44872"use strict";
44873/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__loopCreate__ = __webpack_require__(202);
44874/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__loopFix__ = __webpack_require__(203);
44875/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__loopDestroy__ = __webpack_require__(204);
44876
44877
44878
44879/* harmony default export */ __webpack_exports__["a"] = ({
44880  loopCreate: __WEBPACK_IMPORTED_MODULE_0__loopCreate__["a" /* default */],
44881  loopFix: __WEBPACK_IMPORTED_MODULE_1__loopFix__["a" /* default */],
44882  loopDestroy: __WEBPACK_IMPORTED_MODULE_2__loopDestroy__["a" /* default */]
44883});
44884
44885/***/ }),
44886/* 202 */
44887/***/ (function(module, __webpack_exports__, __webpack_require__) {
44888
44889"use strict";
44890/* harmony export (immutable) */ __webpack_exports__["a"] = loopCreate;
44891/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
44892/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_dom__ = __webpack_require__(3);
44893
44894
44895function loopCreate() {
44896  var swiper = this;
44897  var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
44898  var params = swiper.params,
44899      $wrapperEl = swiper.$wrapperEl; // Remove duplicated slides
44900
44901  $wrapperEl.children("." + params.slideClass + "." + params.slideDuplicateClass).remove();
44902  var slides = $wrapperEl.children("." + params.slideClass);
44903
44904  if (params.loopFillGroupWithBlank) {
44905    var blankSlidesNum = params.slidesPerGroup - slides.length % params.slidesPerGroup;
44906
44907    if (blankSlidesNum !== params.slidesPerGroup) {
44908      for (var i = 0; i < blankSlidesNum; i += 1) {
44909        var blankNode = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(document.createElement('div')).addClass(params.slideClass + " " + params.slideBlankClass);
44910        $wrapperEl.append(blankNode);
44911      }
44912
44913      slides = $wrapperEl.children("." + params.slideClass);
44914    }
44915  }
44916
44917  if (params.slidesPerView === 'auto' && !params.loopedSlides) params.loopedSlides = slides.length;
44918  swiper.loopedSlides = Math.ceil(parseFloat(params.loopedSlides || params.slidesPerView, 10));
44919  swiper.loopedSlides += params.loopAdditionalSlides;
44920
44921  if (swiper.loopedSlides > slides.length) {
44922    swiper.loopedSlides = slides.length;
44923  }
44924
44925  var prependSlides = [];
44926  var appendSlides = [];
44927  slides.each(function (el, index) {
44928    var slide = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(el);
44929
44930    if (index < swiper.loopedSlides) {
44931      appendSlides.push(el);
44932    }
44933
44934    if (index < slides.length && index >= slides.length - swiper.loopedSlides) {
44935      prependSlides.push(el);
44936    }
44937
44938    slide.attr('data-swiper-slide-index', index);
44939  });
44940
44941  for (var _i = 0; _i < appendSlides.length; _i += 1) {
44942    $wrapperEl.append(Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(appendSlides[_i].cloneNode(true)).addClass(params.slideDuplicateClass));
44943  }
44944
44945  for (var _i2 = prependSlides.length - 1; _i2 >= 0; _i2 -= 1) {
44946    $wrapperEl.prepend(Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(prependSlides[_i2].cloneNode(true)).addClass(params.slideDuplicateClass));
44947  }
44948}
44949
44950/***/ }),
44951/* 203 */
44952/***/ (function(module, __webpack_exports__, __webpack_require__) {
44953
44954"use strict";
44955/* harmony export (immutable) */ __webpack_exports__["a"] = loopFix;
44956function loopFix() {
44957  var swiper = this;
44958  swiper.emit('beforeLoopFix');
44959  var activeIndex = swiper.activeIndex,
44960      slides = swiper.slides,
44961      loopedSlides = swiper.loopedSlides,
44962      allowSlidePrev = swiper.allowSlidePrev,
44963      allowSlideNext = swiper.allowSlideNext,
44964      snapGrid = swiper.snapGrid,
44965      rtl = swiper.rtlTranslate;
44966  var newIndex;
44967  swiper.allowSlidePrev = true;
44968  swiper.allowSlideNext = true;
44969  var snapTranslate = -snapGrid[activeIndex];
44970  var diff = snapTranslate - swiper.getTranslate(); // Fix For Negative Oversliding
44971
44972  if (activeIndex < loopedSlides) {
44973    newIndex = slides.length - loopedSlides * 3 + activeIndex;
44974    newIndex += loopedSlides;
44975    var slideChanged = swiper.slideTo(newIndex, 0, false, true);
44976
44977    if (slideChanged && diff !== 0) {
44978      swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);
44979    }
44980  } else if (activeIndex >= slides.length - loopedSlides) {
44981    // Fix For Positive Oversliding
44982    newIndex = -slides.length + activeIndex + loopedSlides;
44983    newIndex += loopedSlides;
44984
44985    var _slideChanged = swiper.slideTo(newIndex, 0, false, true);
44986
44987    if (_slideChanged && diff !== 0) {
44988      swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);
44989    }
44990  }
44991
44992  swiper.allowSlidePrev = allowSlidePrev;
44993  swiper.allowSlideNext = allowSlideNext;
44994  swiper.emit('loopFix');
44995}
44996
44997/***/ }),
44998/* 204 */
44999/***/ (function(module, __webpack_exports__, __webpack_require__) {
45000
45001"use strict";
45002/* harmony export (immutable) */ __webpack_exports__["a"] = loopDestroy;
45003function loopDestroy() {
45004  var swiper = this;
45005  var $wrapperEl = swiper.$wrapperEl,
45006      params = swiper.params,
45007      slides = swiper.slides;
45008  $wrapperEl.children("." + params.slideClass + "." + params.slideDuplicateClass + ",." + params.slideClass + "." + params.slideBlankClass).remove();
45009  slides.removeAttr('data-swiper-slide-index');
45010}
45011
45012/***/ }),
45013/* 205 */
45014/***/ (function(module, __webpack_exports__, __webpack_require__) {
45015
45016"use strict";
45017/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__setGrabCursor__ = __webpack_require__(206);
45018/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__unsetGrabCursor__ = __webpack_require__(207);
45019
45020
45021/* harmony default export */ __webpack_exports__["a"] = ({
45022  setGrabCursor: __WEBPACK_IMPORTED_MODULE_0__setGrabCursor__["a" /* default */],
45023  unsetGrabCursor: __WEBPACK_IMPORTED_MODULE_1__unsetGrabCursor__["a" /* default */]
45024});
45025
45026/***/ }),
45027/* 206 */
45028/***/ (function(module, __webpack_exports__, __webpack_require__) {
45029
45030"use strict";
45031/* harmony export (immutable) */ __webpack_exports__["a"] = setGrabCursor;
45032function setGrabCursor(moving) {
45033  var swiper = this;
45034  if (swiper.support.touch || !swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) return;
45035  var el = swiper.el;
45036  el.style.cursor = 'move';
45037  el.style.cursor = moving ? '-webkit-grabbing' : '-webkit-grab';
45038  el.style.cursor = moving ? '-moz-grabbin' : '-moz-grab';
45039  el.style.cursor = moving ? 'grabbing' : 'grab';
45040}
45041
45042/***/ }),
45043/* 207 */
45044/***/ (function(module, __webpack_exports__, __webpack_require__) {
45045
45046"use strict";
45047/* harmony export (immutable) */ __webpack_exports__["a"] = unsetGrabCursor;
45048function unsetGrabCursor() {
45049  var swiper = this;
45050
45051  if (swiper.support.touch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) {
45052    return;
45053  }
45054
45055  swiper.el.style.cursor = '';
45056}
45057
45058/***/ }),
45059/* 208 */
45060/***/ (function(module, __webpack_exports__, __webpack_require__) {
45061
45062"use strict";
45063/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__appendSlide__ = __webpack_require__(209);
45064/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__prependSlide__ = __webpack_require__(210);
45065/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__addSlide__ = __webpack_require__(211);
45066/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__removeSlide__ = __webpack_require__(212);
45067/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__removeAllSlides__ = __webpack_require__(213);
45068
45069
45070
45071
45072
45073/* harmony default export */ __webpack_exports__["a"] = ({
45074  appendSlide: __WEBPACK_IMPORTED_MODULE_0__appendSlide__["a" /* default */],
45075  prependSlide: __WEBPACK_IMPORTED_MODULE_1__prependSlide__["a" /* default */],
45076  addSlide: __WEBPACK_IMPORTED_MODULE_2__addSlide__["a" /* default */],
45077  removeSlide: __WEBPACK_IMPORTED_MODULE_3__removeSlide__["a" /* default */],
45078  removeAllSlides: __WEBPACK_IMPORTED_MODULE_4__removeAllSlides__["a" /* default */]
45079});
45080
45081/***/ }),
45082/* 209 */
45083/***/ (function(module, __webpack_exports__, __webpack_require__) {
45084
45085"use strict";
45086/* harmony export (immutable) */ __webpack_exports__["a"] = appendSlide;
45087function appendSlide(slides) {
45088  var swiper = this;
45089  var $wrapperEl = swiper.$wrapperEl,
45090      params = swiper.params;
45091
45092  if (params.loop) {
45093    swiper.loopDestroy();
45094  }
45095
45096  if (typeof slides === 'object' && 'length' in slides) {
45097    for (var i = 0; i < slides.length; i += 1) {
45098      if (slides[i]) $wrapperEl.append(slides[i]);
45099    }
45100  } else {
45101    $wrapperEl.append(slides);
45102  }
45103
45104  if (params.loop) {
45105    swiper.loopCreate();
45106  }
45107
45108  if (!(params.observer && swiper.support.observer)) {
45109    swiper.update();
45110  }
45111}
45112
45113/***/ }),
45114/* 210 */
45115/***/ (function(module, __webpack_exports__, __webpack_require__) {
45116
45117"use strict";
45118/* harmony export (immutable) */ __webpack_exports__["a"] = prependSlide;
45119function prependSlide(slides) {
45120  var swiper = this;
45121  var params = swiper.params,
45122      $wrapperEl = swiper.$wrapperEl,
45123      activeIndex = swiper.activeIndex;
45124
45125  if (params.loop) {
45126    swiper.loopDestroy();
45127  }
45128
45129  var newActiveIndex = activeIndex + 1;
45130
45131  if (typeof slides === 'object' && 'length' in slides) {
45132    for (var i = 0; i < slides.length; i += 1) {
45133      if (slides[i]) $wrapperEl.prepend(slides[i]);
45134    }
45135
45136    newActiveIndex = activeIndex + slides.length;
45137  } else {
45138    $wrapperEl.prepend(slides);
45139  }
45140
45141  if (params.loop) {
45142    swiper.loopCreate();
45143  }
45144
45145  if (!(params.observer && swiper.support.observer)) {
45146    swiper.update();
45147  }
45148
45149  swiper.slideTo(newActiveIndex, 0, false);
45150}
45151
45152/***/ }),
45153/* 211 */
45154/***/ (function(module, __webpack_exports__, __webpack_require__) {
45155
45156"use strict";
45157/* harmony export (immutable) */ __webpack_exports__["a"] = addSlide;
45158function addSlide(index, slides) {
45159  var swiper = this;
45160  var $wrapperEl = swiper.$wrapperEl,
45161      params = swiper.params,
45162      activeIndex = swiper.activeIndex;
45163  var activeIndexBuffer = activeIndex;
45164
45165  if (params.loop) {
45166    activeIndexBuffer -= swiper.loopedSlides;
45167    swiper.loopDestroy();
45168    swiper.slides = $wrapperEl.children("." + params.slideClass);
45169  }
45170
45171  var baseLength = swiper.slides.length;
45172
45173  if (index <= 0) {
45174    swiper.prependSlide(slides);
45175    return;
45176  }
45177
45178  if (index >= baseLength) {
45179    swiper.appendSlide(slides);
45180    return;
45181  }
45182
45183  var newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer;
45184  var slidesBuffer = [];
45185
45186  for (var i = baseLength - 1; i >= index; i -= 1) {
45187    var currentSlide = swiper.slides.eq(i);
45188    currentSlide.remove();
45189    slidesBuffer.unshift(currentSlide);
45190  }
45191
45192  if (typeof slides === 'object' && 'length' in slides) {
45193    for (var _i = 0; _i < slides.length; _i += 1) {
45194      if (slides[_i]) $wrapperEl.append(slides[_i]);
45195    }
45196
45197    newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer;
45198  } else {
45199    $wrapperEl.append(slides);
45200  }
45201
45202  for (var _i2 = 0; _i2 < slidesBuffer.length; _i2 += 1) {
45203    $wrapperEl.append(slidesBuffer[_i2]);
45204  }
45205
45206  if (params.loop) {
45207    swiper.loopCreate();
45208  }
45209
45210  if (!(params.observer && swiper.support.observer)) {
45211    swiper.update();
45212  }
45213
45214  if (params.loop) {
45215    swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
45216  } else {
45217    swiper.slideTo(newActiveIndex, 0, false);
45218  }
45219}
45220
45221/***/ }),
45222/* 212 */
45223/***/ (function(module, __webpack_exports__, __webpack_require__) {
45224
45225"use strict";
45226/* harmony export (immutable) */ __webpack_exports__["a"] = removeSlide;
45227function removeSlide(slidesIndexes) {
45228  var swiper = this;
45229  var params = swiper.params,
45230      $wrapperEl = swiper.$wrapperEl,
45231      activeIndex = swiper.activeIndex;
45232  var activeIndexBuffer = activeIndex;
45233
45234  if (params.loop) {
45235    activeIndexBuffer -= swiper.loopedSlides;
45236    swiper.loopDestroy();
45237    swiper.slides = $wrapperEl.children("." + params.slideClass);
45238  }
45239
45240  var newActiveIndex = activeIndexBuffer;
45241  var indexToRemove;
45242
45243  if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) {
45244    for (var i = 0; i < slidesIndexes.length; i += 1) {
45245      indexToRemove = slidesIndexes[i];
45246      if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove();
45247      if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
45248    }
45249
45250    newActiveIndex = Math.max(newActiveIndex, 0);
45251  } else {
45252    indexToRemove = slidesIndexes;
45253    if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove();
45254    if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
45255    newActiveIndex = Math.max(newActiveIndex, 0);
45256  }
45257
45258  if (params.loop) {
45259    swiper.loopCreate();
45260  }
45261
45262  if (!(params.observer && swiper.support.observer)) {
45263    swiper.update();
45264  }
45265
45266  if (params.loop) {
45267    swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
45268  } else {
45269    swiper.slideTo(newActiveIndex, 0, false);
45270  }
45271}
45272
45273/***/ }),
45274/* 213 */
45275/***/ (function(module, __webpack_exports__, __webpack_require__) {
45276
45277"use strict";
45278/* harmony export (immutable) */ __webpack_exports__["a"] = removeAllSlides;
45279function removeAllSlides() {
45280  var swiper = this;
45281  var slidesIndexes = [];
45282
45283  for (var i = 0; i < swiper.slides.length; i += 1) {
45284    slidesIndexes.push(i);
45285  }
45286
45287  swiper.removeSlide(slidesIndexes);
45288}
45289
45290/***/ }),
45291/* 214 */
45292/***/ (function(module, __webpack_exports__, __webpack_require__) {
45293
45294"use strict";
45295/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
45296/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__onTouchStart__ = __webpack_require__(215);
45297/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__onTouchMove__ = __webpack_require__(216);
45298/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__onTouchEnd__ = __webpack_require__(217);
45299/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__onResize__ = __webpack_require__(218);
45300/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__onClick__ = __webpack_require__(219);
45301/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__onScroll__ = __webpack_require__(220);
45302
45303
45304
45305
45306
45307
45308
45309var dummyEventAttached = false;
45310
45311function dummyEventListener() {}
45312
45313function attachEvents() {
45314  var swiper = this;
45315  var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
45316  var params = swiper.params,
45317      touchEvents = swiper.touchEvents,
45318      el = swiper.el,
45319      wrapperEl = swiper.wrapperEl,
45320      device = swiper.device,
45321      support = swiper.support;
45322  swiper.onTouchStart = __WEBPACK_IMPORTED_MODULE_1__onTouchStart__["a" /* default */].bind(swiper);
45323  swiper.onTouchMove = __WEBPACK_IMPORTED_MODULE_2__onTouchMove__["a" /* default */].bind(swiper);
45324  swiper.onTouchEnd = __WEBPACK_IMPORTED_MODULE_3__onTouchEnd__["a" /* default */].bind(swiper);
45325
45326  if (params.cssMode) {
45327    swiper.onScroll = __WEBPACK_IMPORTED_MODULE_6__onScroll__["a" /* default */].bind(swiper);
45328  }
45329
45330  swiper.onClick = __WEBPACK_IMPORTED_MODULE_5__onClick__["a" /* default */].bind(swiper);
45331  var capture = !!params.nested; // Touch Events
45332
45333  if (!support.touch && support.pointerEvents) {
45334    el.addEventListener(touchEvents.start, swiper.onTouchStart, false);
45335    document.addEventListener(touchEvents.move, swiper.onTouchMove, capture);
45336    document.addEventListener(touchEvents.end, swiper.onTouchEnd, false);
45337  } else {
45338    if (support.touch) {
45339      var passiveListener = touchEvents.start === 'touchstart' && support.passiveListener && params.passiveListeners ? {
45340        passive: true,
45341        capture: false
45342      } : false;
45343      el.addEventListener(touchEvents.start, swiper.onTouchStart, passiveListener);
45344      el.addEventListener(touchEvents.move, swiper.onTouchMove, support.passiveListener ? {
45345        passive: false,
45346        capture: capture
45347      } : capture);
45348      el.addEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener);
45349
45350      if (touchEvents.cancel) {
45351        el.addEventListener(touchEvents.cancel, swiper.onTouchEnd, passiveListener);
45352      }
45353
45354      if (!dummyEventAttached) {
45355        document.addEventListener('touchstart', dummyEventListener);
45356        dummyEventAttached = true;
45357      }
45358    }
45359
45360    if (params.simulateTouch && !device.ios && !device.android || params.simulateTouch && !support.touch && device.ios) {
45361      el.addEventListener('mousedown', swiper.onTouchStart, false);
45362      document.addEventListener('mousemove', swiper.onTouchMove, capture);
45363      document.addEventListener('mouseup', swiper.onTouchEnd, false);
45364    }
45365  } // Prevent Links Clicks
45366
45367
45368  if (params.preventClicks || params.preventClicksPropagation) {
45369    el.addEventListener('click', swiper.onClick, true);
45370  }
45371
45372  if (params.cssMode) {
45373    wrapperEl.addEventListener('scroll', swiper.onScroll);
45374  } // Resize handler
45375
45376
45377  if (params.updateOnWindowResize) {
45378    swiper.on(device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', __WEBPACK_IMPORTED_MODULE_4__onResize__["a" /* default */], true);
45379  } else {
45380    swiper.on('observerUpdate', __WEBPACK_IMPORTED_MODULE_4__onResize__["a" /* default */], true);
45381  }
45382}
45383
45384function detachEvents() {
45385  var swiper = this;
45386  var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
45387  var params = swiper.params,
45388      touchEvents = swiper.touchEvents,
45389      el = swiper.el,
45390      wrapperEl = swiper.wrapperEl,
45391      device = swiper.device,
45392      support = swiper.support;
45393  var capture = !!params.nested; // Touch Events
45394
45395  if (!support.touch && support.pointerEvents) {
45396    el.removeEventListener(touchEvents.start, swiper.onTouchStart, false);
45397    document.removeEventListener(touchEvents.move, swiper.onTouchMove, capture);
45398    document.removeEventListener(touchEvents.end, swiper.onTouchEnd, false);
45399  } else {
45400    if (support.touch) {
45401      var passiveListener = touchEvents.start === 'onTouchStart' && support.passiveListener && params.passiveListeners ? {
45402        passive: true,
45403        capture: false
45404      } : false;
45405      el.removeEventListener(touchEvents.start, swiper.onTouchStart, passiveListener);
45406      el.removeEventListener(touchEvents.move, swiper.onTouchMove, capture);
45407      el.removeEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener);
45408
45409      if (touchEvents.cancel) {
45410        el.removeEventListener(touchEvents.cancel, swiper.onTouchEnd, passiveListener);
45411      }
45412    }
45413
45414    if (params.simulateTouch && !device.ios && !device.android || params.simulateTouch && !support.touch && device.ios) {
45415      el.removeEventListener('mousedown', swiper.onTouchStart, false);
45416      document.removeEventListener('mousemove', swiper.onTouchMove, capture);
45417      document.removeEventListener('mouseup', swiper.onTouchEnd, false);
45418    }
45419  } // Prevent Links Clicks
45420
45421
45422  if (params.preventClicks || params.preventClicksPropagation) {
45423    el.removeEventListener('click', swiper.onClick, true);
45424  }
45425
45426  if (params.cssMode) {
45427    wrapperEl.removeEventListener('scroll', swiper.onScroll);
45428  } // Resize handler
45429
45430
45431  swiper.off(device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', __WEBPACK_IMPORTED_MODULE_4__onResize__["a" /* default */]);
45432}
45433
45434/* harmony default export */ __webpack_exports__["a"] = ({
45435  attachEvents: attachEvents,
45436  detachEvents: detachEvents
45437});
45438
45439/***/ }),
45440/* 215 */
45441/***/ (function(module, __webpack_exports__, __webpack_require__) {
45442
45443"use strict";
45444/* harmony export (immutable) */ __webpack_exports__["a"] = onTouchStart;
45445/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
45446/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_dom__ = __webpack_require__(3);
45447/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_utils__ = __webpack_require__(1);
45448
45449
45450 // Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
45451
45452function closestElement(selector, base) {
45453  if (base === void 0) {
45454    base = this;
45455  }
45456
45457  function __closestFrom(el) {
45458    if (!el || el === Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])() || el === Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])()) return null;
45459    if (el.assignedSlot) el = el.assignedSlot;
45460    var found = el.closest(selector);
45461    return found || __closestFrom(el.getRootNode().host);
45462  }
45463
45464  return __closestFrom(base);
45465}
45466
45467function onTouchStart(event) {
45468  var swiper = this;
45469  var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
45470  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
45471  var data = swiper.touchEventsData;
45472  var params = swiper.params,
45473      touches = swiper.touches,
45474      enabled = swiper.enabled;
45475  if (!enabled) return;
45476
45477  if (swiper.animating && params.preventInteractionOnTransition) {
45478    return;
45479  }
45480
45481  var e = event;
45482  if (e.originalEvent) e = e.originalEvent;
45483  var $targetEl = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(e.target);
45484
45485  if (params.touchEventsTarget === 'wrapper') {
45486    if (!$targetEl.closest(swiper.wrapperEl).length) return;
45487  }
45488
45489  data.isTouchEvent = e.type === 'touchstart';
45490  if (!data.isTouchEvent && 'which' in e && e.which === 3) return;
45491  if (!data.isTouchEvent && 'button' in e && e.button > 0) return;
45492  if (data.isTouched && data.isMoved) return; // change target el for shadow root component
45493
45494  var swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
45495
45496  if (swipingClassHasValue && e.target && e.target.shadowRoot && event.path && event.path[0]) {
45497    $targetEl = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(event.path[0]);
45498  }
45499
45500  var noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : "." + params.noSwipingClass;
45501  var isTargetShadow = !!(e.target && e.target.shadowRoot); // use closestElement for shadow root element to get the actual closest for nested shadow root element
45502
45503  if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, e.target) : $targetEl.closest(noSwipingSelector)[0])) {
45504    swiper.allowClick = true;
45505    return;
45506  }
45507
45508  if (params.swipeHandler) {
45509    if (!$targetEl.closest(params.swipeHandler)[0]) return;
45510  }
45511
45512  touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
45513  touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
45514  var startX = touches.currentX;
45515  var startY = touches.currentY; // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
45516
45517  var edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection;
45518  var edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold;
45519
45520  if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) {
45521    if (edgeSwipeDetection === 'prevent') {
45522      event.preventDefault();
45523    } else {
45524      return;
45525    }
45526  }
45527
45528  Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])(data, {
45529    isTouched: true,
45530    isMoved: false,
45531    allowTouchCallbacks: true,
45532    isScrolling: undefined,
45533    startMoving: undefined
45534  });
45535  touches.startX = startX;
45536  touches.startY = startY;
45537  data.touchStartTime = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["i" /* now */])();
45538  swiper.allowClick = true;
45539  swiper.updateSize();
45540  swiper.swipeDirection = undefined;
45541  if (params.threshold > 0) data.allowThresholdMove = false;
45542
45543  if (e.type !== 'touchstart') {
45544    var preventDefault = true;
45545    if ($targetEl.is(data.focusableElements)) preventDefault = false;
45546
45547    if (document.activeElement && Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(document.activeElement).is(data.focusableElements) && document.activeElement !== $targetEl[0]) {
45548      document.activeElement.blur();
45549    }
45550
45551    var shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
45552
45553    if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !$targetEl[0].isContentEditable) {
45554      e.preventDefault();
45555    }
45556  }
45557
45558  swiper.emit('touchStart', e);
45559}
45560
45561/***/ }),
45562/* 216 */
45563/***/ (function(module, __webpack_exports__, __webpack_require__) {
45564
45565"use strict";
45566/* harmony export (immutable) */ __webpack_exports__["a"] = onTouchMove;
45567/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
45568/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_dom__ = __webpack_require__(3);
45569/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_utils__ = __webpack_require__(1);
45570
45571
45572
45573function onTouchMove(event) {
45574  var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
45575  var swiper = this;
45576  var data = swiper.touchEventsData;
45577  var params = swiper.params,
45578      touches = swiper.touches,
45579      rtl = swiper.rtlTranslate,
45580      enabled = swiper.enabled;
45581  if (!enabled) return;
45582  var e = event;
45583  if (e.originalEvent) e = e.originalEvent;
45584
45585  if (!data.isTouched) {
45586    if (data.startMoving && data.isScrolling) {
45587      swiper.emit('touchMoveOpposite', e);
45588    }
45589
45590    return;
45591  }
45592
45593  if (data.isTouchEvent && e.type !== 'touchmove') return;
45594  var targetTouch = e.type === 'touchmove' && e.targetTouches && (e.targetTouches[0] || e.changedTouches[0]);
45595  var pageX = e.type === 'touchmove' ? targetTouch.pageX : e.pageX;
45596  var pageY = e.type === 'touchmove' ? targetTouch.pageY : e.pageY;
45597
45598  if (e.preventedByNestedSwiper) {
45599    touches.startX = pageX;
45600    touches.startY = pageY;
45601    return;
45602  }
45603
45604  if (!swiper.allowTouchMove) {
45605    // isMoved = true;
45606    swiper.allowClick = false;
45607
45608    if (data.isTouched) {
45609      Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])(touches, {
45610        startX: pageX,
45611        startY: pageY,
45612        currentX: pageX,
45613        currentY: pageY
45614      });
45615      data.touchStartTime = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["i" /* now */])();
45616    }
45617
45618    return;
45619  }
45620
45621  if (data.isTouchEvent && params.touchReleaseOnEdges && !params.loop) {
45622    if (swiper.isVertical()) {
45623      // Vertical
45624      if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) {
45625        data.isTouched = false;
45626        data.isMoved = false;
45627        return;
45628      }
45629    } else if (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX && swiper.translate >= swiper.minTranslate()) {
45630      return;
45631    }
45632  }
45633
45634  if (data.isTouchEvent && document.activeElement) {
45635    if (e.target === document.activeElement && Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(e.target).is(data.focusableElements)) {
45636      data.isMoved = true;
45637      swiper.allowClick = false;
45638      return;
45639    }
45640  }
45641
45642  if (data.allowTouchCallbacks) {
45643    swiper.emit('touchMove', e);
45644  }
45645
45646  if (e.targetTouches && e.targetTouches.length > 1) return;
45647  touches.currentX = pageX;
45648  touches.currentY = pageY;
45649  var diffX = touches.currentX - touches.startX;
45650  var diffY = touches.currentY - touches.startY;
45651  if (swiper.params.threshold && Math.sqrt(Math.pow(diffX, 2) + Math.pow(diffY, 2)) < swiper.params.threshold) return;
45652
45653  if (typeof data.isScrolling === 'undefined') {
45654    var touchAngle;
45655
45656    if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX === touches.startX) {
45657      data.isScrolling = false;
45658    } else {
45659      // eslint-disable-next-line
45660      if (diffX * diffX + diffY * diffY >= 25) {
45661        touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;
45662        data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle;
45663      }
45664    }
45665  }
45666
45667  if (data.isScrolling) {
45668    swiper.emit('touchMoveOpposite', e);
45669  }
45670
45671  if (typeof data.startMoving === 'undefined') {
45672    if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {
45673      data.startMoving = true;
45674    }
45675  }
45676
45677  if (data.isScrolling) {
45678    data.isTouched = false;
45679    return;
45680  }
45681
45682  if (!data.startMoving) {
45683    return;
45684  }
45685
45686  swiper.allowClick = false;
45687
45688  if (!params.cssMode && e.cancelable) {
45689    e.preventDefault();
45690  }
45691
45692  if (params.touchMoveStopPropagation && !params.nested) {
45693    e.stopPropagation();
45694  }
45695
45696  if (!data.isMoved) {
45697    if (params.loop) {
45698      swiper.loopFix();
45699    }
45700
45701    data.startTranslate = swiper.getTranslate();
45702    swiper.setTransition(0);
45703
45704    if (swiper.animating) {
45705      swiper.$wrapperEl.trigger('webkitTransitionEnd transitionend');
45706    }
45707
45708    data.allowMomentumBounce = false; // Grab Cursor
45709
45710    if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
45711      swiper.setGrabCursor(true);
45712    }
45713
45714    swiper.emit('sliderFirstMove', e);
45715  }
45716
45717  swiper.emit('sliderMove', e);
45718  data.isMoved = true;
45719  var diff = swiper.isHorizontal() ? diffX : diffY;
45720  touches.diff = diff;
45721  diff *= params.touchRatio;
45722  if (rtl) diff = -diff;
45723  swiper.swipeDirection = diff > 0 ? 'prev' : 'next';
45724  data.currentTranslate = diff + data.startTranslate;
45725  var disableParentSwiper = true;
45726  var resistanceRatio = params.resistanceRatio;
45727
45728  if (params.touchReleaseOnEdges) {
45729    resistanceRatio = 0;
45730  }
45731
45732  if (diff > 0 && data.currentTranslate > swiper.minTranslate()) {
45733    disableParentSwiper = false;
45734    if (params.resistance) data.currentTranslate = swiper.minTranslate() - 1 + Math.pow(-swiper.minTranslate() + data.startTranslate + diff, resistanceRatio);
45735  } else if (diff < 0 && data.currentTranslate < swiper.maxTranslate()) {
45736    disableParentSwiper = false;
45737    if (params.resistance) data.currentTranslate = swiper.maxTranslate() + 1 - Math.pow(swiper.maxTranslate() - data.startTranslate - diff, resistanceRatio);
45738  }
45739
45740  if (disableParentSwiper) {
45741    e.preventedByNestedSwiper = true;
45742  } // Directions locks
45743
45744
45745  if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {
45746    data.currentTranslate = data.startTranslate;
45747  }
45748
45749  if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {
45750    data.currentTranslate = data.startTranslate;
45751  }
45752
45753  if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
45754    data.currentTranslate = data.startTranslate;
45755  } // Threshold
45756
45757
45758  if (params.threshold > 0) {
45759    if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
45760      if (!data.allowThresholdMove) {
45761        data.allowThresholdMove = true;
45762        touches.startX = touches.currentX;
45763        touches.startY = touches.currentY;
45764        data.currentTranslate = data.startTranslate;
45765        touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;
45766        return;
45767      }
45768    } else {
45769      data.currentTranslate = data.startTranslate;
45770      return;
45771    }
45772  }
45773
45774  if (!params.followFinger || params.cssMode) return; // Update active index in free mode
45775
45776  if (params.freeMode || params.watchSlidesProgress || params.watchSlidesVisibility) {
45777    swiper.updateActiveIndex();
45778    swiper.updateSlidesClasses();
45779  }
45780
45781  if (params.freeMode) {
45782    // Velocity
45783    if (data.velocities.length === 0) {
45784      data.velocities.push({
45785        position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],
45786        time: data.touchStartTime
45787      });
45788    }
45789
45790    data.velocities.push({
45791      position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],
45792      time: Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["i" /* now */])()
45793    });
45794  } // Update progress
45795
45796
45797  swiper.updateProgress(data.currentTranslate); // Update translate
45798
45799  swiper.setTranslate(data.currentTranslate);
45800}
45801
45802/***/ }),
45803/* 217 */
45804/***/ (function(module, __webpack_exports__, __webpack_require__) {
45805
45806"use strict";
45807/* harmony export (immutable) */ __webpack_exports__["a"] = onTouchEnd;
45808/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_utils__ = __webpack_require__(1);
45809
45810function onTouchEnd(event) {
45811  var swiper = this;
45812  var data = swiper.touchEventsData;
45813  var params = swiper.params,
45814      touches = swiper.touches,
45815      rtl = swiper.rtlTranslate,
45816      $wrapperEl = swiper.$wrapperEl,
45817      slidesGrid = swiper.slidesGrid,
45818      snapGrid = swiper.snapGrid,
45819      enabled = swiper.enabled;
45820  if (!enabled) return;
45821  var e = event;
45822  if (e.originalEvent) e = e.originalEvent;
45823
45824  if (data.allowTouchCallbacks) {
45825    swiper.emit('touchEnd', e);
45826  }
45827
45828  data.allowTouchCallbacks = false;
45829
45830  if (!data.isTouched) {
45831    if (data.isMoved && params.grabCursor) {
45832      swiper.setGrabCursor(false);
45833    }
45834
45835    data.isMoved = false;
45836    data.startMoving = false;
45837    return;
45838  } // Return Grab Cursor
45839
45840
45841  if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
45842    swiper.setGrabCursor(false);
45843  } // Time diff
45844
45845
45846  var touchEndTime = Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["i" /* now */])();
45847  var timeDiff = touchEndTime - data.touchStartTime; // Tap, doubleTap, Click
45848
45849  if (swiper.allowClick) {
45850    swiper.updateClickedSlide(e);
45851    swiper.emit('tap click', e);
45852
45853    if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {
45854      swiper.emit('doubleTap doubleClick', e);
45855    }
45856  }
45857
45858  data.lastClickTime = Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["i" /* now */])();
45859  Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["h" /* nextTick */])(function () {
45860    if (!swiper.destroyed) swiper.allowClick = true;
45861  });
45862
45863  if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 || data.currentTranslate === data.startTranslate) {
45864    data.isTouched = false;
45865    data.isMoved = false;
45866    data.startMoving = false;
45867    return;
45868  }
45869
45870  data.isTouched = false;
45871  data.isMoved = false;
45872  data.startMoving = false;
45873  var currentPos;
45874
45875  if (params.followFinger) {
45876    currentPos = rtl ? swiper.translate : -swiper.translate;
45877  } else {
45878    currentPos = -data.currentTranslate;
45879  }
45880
45881  if (params.cssMode) {
45882    return;
45883  }
45884
45885  if (params.freeMode) {
45886    if (currentPos < -swiper.minTranslate()) {
45887      swiper.slideTo(swiper.activeIndex);
45888      return;
45889    }
45890
45891    if (currentPos > -swiper.maxTranslate()) {
45892      if (swiper.slides.length < snapGrid.length) {
45893        swiper.slideTo(snapGrid.length - 1);
45894      } else {
45895        swiper.slideTo(swiper.slides.length - 1);
45896      }
45897
45898      return;
45899    }
45900
45901    if (params.freeModeMomentum) {
45902      if (data.velocities.length > 1) {
45903        var lastMoveEvent = data.velocities.pop();
45904        var velocityEvent = data.velocities.pop();
45905        var distance = lastMoveEvent.position - velocityEvent.position;
45906        var time = lastMoveEvent.time - velocityEvent.time;
45907        swiper.velocity = distance / time;
45908        swiper.velocity /= 2;
45909
45910        if (Math.abs(swiper.velocity) < params.freeModeMinimumVelocity) {
45911          swiper.velocity = 0;
45912        } // this implies that the user stopped moving a finger then released.
45913        // There would be no events with distance zero, so the last event is stale.
45914
45915
45916        if (time > 150 || Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["i" /* now */])() - lastMoveEvent.time > 300) {
45917          swiper.velocity = 0;
45918        }
45919      } else {
45920        swiper.velocity = 0;
45921      }
45922
45923      swiper.velocity *= params.freeModeMomentumVelocityRatio;
45924      data.velocities.length = 0;
45925      var momentumDuration = 1000 * params.freeModeMomentumRatio;
45926      var momentumDistance = swiper.velocity * momentumDuration;
45927      var newPosition = swiper.translate + momentumDistance;
45928      if (rtl) newPosition = -newPosition;
45929      var doBounce = false;
45930      var afterBouncePosition;
45931      var bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeModeMomentumBounceRatio;
45932      var needsLoopFix;
45933
45934      if (newPosition < swiper.maxTranslate()) {
45935        if (params.freeModeMomentumBounce) {
45936          if (newPosition + swiper.maxTranslate() < -bounceAmount) {
45937            newPosition = swiper.maxTranslate() - bounceAmount;
45938          }
45939
45940          afterBouncePosition = swiper.maxTranslate();
45941          doBounce = true;
45942          data.allowMomentumBounce = true;
45943        } else {
45944          newPosition = swiper.maxTranslate();
45945        }
45946
45947        if (params.loop && params.centeredSlides) needsLoopFix = true;
45948      } else if (newPosition > swiper.minTranslate()) {
45949        if (params.freeModeMomentumBounce) {
45950          if (newPosition - swiper.minTranslate() > bounceAmount) {
45951            newPosition = swiper.minTranslate() + bounceAmount;
45952          }
45953
45954          afterBouncePosition = swiper.minTranslate();
45955          doBounce = true;
45956          data.allowMomentumBounce = true;
45957        } else {
45958          newPosition = swiper.minTranslate();
45959        }
45960
45961        if (params.loop && params.centeredSlides) needsLoopFix = true;
45962      } else if (params.freeModeSticky) {
45963        var nextSlide;
45964
45965        for (var j = 0; j < snapGrid.length; j += 1) {
45966          if (snapGrid[j] > -newPosition) {
45967            nextSlide = j;
45968            break;
45969          }
45970        }
45971
45972        if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') {
45973          newPosition = snapGrid[nextSlide];
45974        } else {
45975          newPosition = snapGrid[nextSlide - 1];
45976        }
45977
45978        newPosition = -newPosition;
45979      }
45980
45981      if (needsLoopFix) {
45982        swiper.once('transitionEnd', function () {
45983          swiper.loopFix();
45984        });
45985      } // Fix duration
45986
45987
45988      if (swiper.velocity !== 0) {
45989        if (rtl) {
45990          momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);
45991        } else {
45992          momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);
45993        }
45994
45995        if (params.freeModeSticky) {
45996          // If freeModeSticky is active and the user ends a swipe with a slow-velocity
45997          // event, then durations can be 20+ seconds to slide one (or zero!) slides.
45998          // It's easy to see this when simulating touch with mouse events. To fix this,
45999          // limit single-slide swipes to the default slide duration. This also has the
46000          // nice side effect of matching slide speed if the user stopped moving before
46001          // lifting finger or mouse vs. moving slowly before lifting the finger/mouse.
46002          // For faster swipes, also apply limits (albeit higher ones).
46003          var moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);
46004          var currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];
46005
46006          if (moveDistance < currentSlideSize) {
46007            momentumDuration = params.speed;
46008          } else if (moveDistance < 2 * currentSlideSize) {
46009            momentumDuration = params.speed * 1.5;
46010          } else {
46011            momentumDuration = params.speed * 2.5;
46012          }
46013        }
46014      } else if (params.freeModeSticky) {
46015        swiper.slideToClosest();
46016        return;
46017      }
46018
46019      if (params.freeModeMomentumBounce && doBounce) {
46020        swiper.updateProgress(afterBouncePosition);
46021        swiper.setTransition(momentumDuration);
46022        swiper.setTranslate(newPosition);
46023        swiper.transitionStart(true, swiper.swipeDirection);
46024        swiper.animating = true;
46025        $wrapperEl.transitionEnd(function () {
46026          if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;
46027          swiper.emit('momentumBounce');
46028          swiper.setTransition(params.speed);
46029          setTimeout(function () {
46030            swiper.setTranslate(afterBouncePosition);
46031            $wrapperEl.transitionEnd(function () {
46032              if (!swiper || swiper.destroyed) return;
46033              swiper.transitionEnd();
46034            });
46035          }, 0);
46036        });
46037      } else if (swiper.velocity) {
46038        swiper.updateProgress(newPosition);
46039        swiper.setTransition(momentumDuration);
46040        swiper.setTranslate(newPosition);
46041        swiper.transitionStart(true, swiper.swipeDirection);
46042
46043        if (!swiper.animating) {
46044          swiper.animating = true;
46045          $wrapperEl.transitionEnd(function () {
46046            if (!swiper || swiper.destroyed) return;
46047            swiper.transitionEnd();
46048          });
46049        }
46050      } else {
46051        swiper.emit('_freeModeNoMomentumRelease');
46052        swiper.updateProgress(newPosition);
46053      }
46054
46055      swiper.updateActiveIndex();
46056      swiper.updateSlidesClasses();
46057    } else if (params.freeModeSticky) {
46058      swiper.slideToClosest();
46059      return;
46060    } else if (params.freeMode) {
46061      swiper.emit('_freeModeNoMomentumRelease');
46062    }
46063
46064    if (!params.freeModeMomentum || timeDiff >= params.longSwipesMs) {
46065      swiper.updateProgress();
46066      swiper.updateActiveIndex();
46067      swiper.updateSlidesClasses();
46068    }
46069
46070    return;
46071  } // Find current slide
46072
46073
46074  var stopIndex = 0;
46075  var groupSize = swiper.slidesSizesGrid[0];
46076
46077  for (var i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {
46078    var _increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
46079
46080    if (typeof slidesGrid[i + _increment] !== 'undefined') {
46081      if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + _increment]) {
46082        stopIndex = i;
46083        groupSize = slidesGrid[i + _increment] - slidesGrid[i];
46084      }
46085    } else if (currentPos >= slidesGrid[i]) {
46086      stopIndex = i;
46087      groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];
46088    }
46089  } // Find current slide size
46090
46091
46092  var ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
46093  var increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
46094
46095  if (timeDiff > params.longSwipesMs) {
46096    // Long touches
46097    if (!params.longSwipes) {
46098      swiper.slideTo(swiper.activeIndex);
46099      return;
46100    }
46101
46102    if (swiper.swipeDirection === 'next') {
46103      if (ratio >= params.longSwipesRatio) swiper.slideTo(stopIndex + increment);else swiper.slideTo(stopIndex);
46104    }
46105
46106    if (swiper.swipeDirection === 'prev') {
46107      if (ratio > 1 - params.longSwipesRatio) swiper.slideTo(stopIndex + increment);else swiper.slideTo(stopIndex);
46108    }
46109  } else {
46110    // Short swipes
46111    if (!params.shortSwipes) {
46112      swiper.slideTo(swiper.activeIndex);
46113      return;
46114    }
46115
46116    var isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl);
46117
46118    if (!isNavButtonTarget) {
46119      if (swiper.swipeDirection === 'next') {
46120        swiper.slideTo(stopIndex + increment);
46121      }
46122
46123      if (swiper.swipeDirection === 'prev') {
46124        swiper.slideTo(stopIndex);
46125      }
46126    } else if (e.target === swiper.navigation.nextEl) {
46127      swiper.slideTo(stopIndex + increment);
46128    } else {
46129      swiper.slideTo(stopIndex);
46130    }
46131  }
46132}
46133
46134/***/ }),
46135/* 218 */
46136/***/ (function(module, __webpack_exports__, __webpack_require__) {
46137
46138"use strict";
46139/* harmony export (immutable) */ __webpack_exports__["a"] = onResize;
46140function onResize() {
46141  var swiper = this;
46142  var params = swiper.params,
46143      el = swiper.el;
46144  if (el && el.offsetWidth === 0) return;
46144 // Breakpoints
46145
46146  if (params.breakpoints) {
46147    swiper.setBreakpoint();
46148  } // Save locks
46149
46150
46151  var allowSlideNext = swiper.allowSlideNext,
46152      allowSlidePrev = swiper.allowSlidePrev,
46153      snapGrid = swiper.snapGrid; // Disable locks on resize
46154
46155  swiper.allowSlideNext = true;
46156  swiper.allowSlidePrev = true;
46157  swiper.updateSize();
46158  swiper.updateSlides();
46159  swiper.updateSlidesClasses();
46160
46161  if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides) {
46162    swiper.slideTo(swiper.slides.length - 1, 0, false, true);
46163  } else {
46164    swiper.slideTo(swiper.activeIndex, 0, false, true);
46165  }
46166
46167  if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
46168    swiper.autoplay.run();
46169  } // Return locks after resize
46170
46171
46172  swiper.allowSlidePrev = allowSlidePrev;
46173  swiper.allowSlideNext = allowSlideNext;
46174
46175  if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
46176    swiper.checkOverflow();
46177  }
46178}
46179
46180/***/ }),
46181/* 219 */
46182/***/ (function(module, __webpack_exports__, __webpack_require__) {
46183
46184"use strict";
46185/* harmony export (immutable) */ __webpack_exports__["a"] = onClick;
46186function onClick(e) {
46187  var swiper = this;
46188  if (!swiper.enabled) return;
46189
46190  if (!swiper.allowClick) {
46191    if (swiper.params.preventClicks) e.preventDefault();
46192
46193    if (swiper.params.preventClicksPropagation && swiper.animating) {
46194      e.stopPropagation();
46195      e.stopImmediatePropagation();
46196    }
46197  }
46198}
46199
46200/***/ }),
46201/* 220 */
46202/***/ (function(module, __webpack_exports__, __webpack_require__) {
46203
46204"use strict";
46205/* harmony export (immutable) */ __webpack_exports__["a"] = onScroll;
46206function onScroll() {
46207  var swiper = this;
46208  var wrapperEl = swiper.wrapperEl,
46209      rtlTranslate = swiper.rtlTranslate,
46210      enabled = swiper.enabled;
46211  if (!enabled) return;
46212  swiper.previousTranslate = swiper.translate;
46213
46214  if (swiper.isHorizontal()) {
46215    if (rtlTranslate) {
46216      swiper.translate = wrapperEl.scrollWidth - wrapperEl.offsetWidth - wrapperEl.scrollLeft;
46217    } else {
46218      swiper.translate = -wrapperEl.scrollLeft;
46219    }
46220  } else {
46221    swiper.translate = -wrapperEl.scrollTop;
46222  } // eslint-disable-next-line
46223
46224
46225  if (swiper.translate === -0) swiper.translate = 0;
46226  swiper.updateActiveIndex();
46227  swiper.updateSlidesClasses();
46228  var newProgress;
46229  var translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
46230
46231  if (translatesDiff === 0) {
46232    newProgress = 0;
46233  } else {
46234    newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;
46235  }
46236
46237  if (newProgress !== swiper.progress) {
46238    swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);
46239  }
46240
46241  swiper.emit('setTranslate', swiper.translate, false);
46242}
46243
46244/***/ }),
46245/* 221 */
46246/***/ (function(module, __webpack_exports__, __webpack_require__) {
46247
46248"use strict";
46249/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__setBreakpoint__ = __webpack_require__(222);
46250/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__getBreakpoint__ = __webpack_require__(223);
46251
46252
46253/* harmony default export */ __webpack_exports__["a"] = ({
46254  setBreakpoint: __WEBPACK_IMPORTED_MODULE_0__setBreakpoint__["a" /* default */],
46255  getBreakpoint: __WEBPACK_IMPORTED_MODULE_1__getBreakpoint__["a" /* default */]
46256});
46257
46258/***/ }),
46259/* 222 */
46260/***/ (function(module, __webpack_exports__, __webpack_require__) {
46261
46262"use strict";
46263/* harmony export (immutable) */ __webpack_exports__["a"] = setBreakpoint;
46264/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_utils__ = __webpack_require__(1);
46265
46266function setBreakpoint() {
46267  var swiper = this;
46268  var activeIndex = swiper.activeIndex,
46269      initialized = swiper.initialized,
46270      _swiper$loopedSlides = swiper.loopedSlides,
46271      loopedSlides = _swiper$loopedSlides === void 0 ? 0 : _swiper$loopedSlides,
46272      params = swiper.params,
46273      $el = swiper.$el;
46274  var breakpoints = params.breakpoints;
46275  if (!breakpoints || breakpoints && Object.keys(breakpoints).length === 0) return; // Get breakpoint for window width and update parameters
46276
46277  var breakpoint = swiper.getBreakpoint(breakpoints, swiper.params.breakpointsBase, swiper.el);
46278  if (!breakpoint || swiper.currentBreakpoint === breakpoint) return;
46279  var breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;
46280
46281  if (breakpointOnlyParams) {
46282    ['slidesPerView', 'spaceBetween', 'slidesPerGroup', 'slidesPerGroupSkip', 'slidesPerColumn'].forEach(function (param) {
46283      var paramValue = breakpointOnlyParams[param];
46284      if (typeof paramValue === 'undefined') return;
46285
46286      if (param === 'slidesPerView' && (paramValue === 'AUTO' || paramValue === 'auto')) {
46287        breakpointOnlyParams[param] = 'auto';
46288      } else if (param === 'slidesPerView') {
46289        breakpointOnlyParams[param] = parseFloat(paramValue);
46290      } else {
46291        breakpointOnlyParams[param] = parseInt(paramValue, 10);
46292      }
46293    });
46294  }
46295
46296  var breakpointParams = breakpointOnlyParams || swiper.originalParams;
46297  var wasMultiRow = params.slidesPerColumn > 1;
46298  var isMultiRow = breakpointParams.slidesPerColumn > 1;
46299  var wasEnabled = params.enabled;
46300
46301  if (wasMultiRow && !isMultiRow) {
46302    $el.removeClass(params.containerModifierClass + "multirow " + params.containerModifierClass + "multirow-column");
46303    swiper.emitContainerClasses();
46304  } else if (!wasMultiRow && isMultiRow) {
46305    $el.addClass(params.containerModifierClass + "multirow");
46306
46307    if (breakpointParams.slidesPerColumnFill && breakpointParams.slidesPerColumnFill === 'column' || !breakpointParams.slidesPerColumnFill && params.slidesPerColumnFill === 'column') {
46308      $el.addClass(params.containerModifierClass + "multirow-column");
46309    }
46310
46311    swiper.emitContainerClasses();
46312  }
46313
46314  var directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;
46315  var needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);
46316
46317  if (directionChanged && initialized) {
46318    swiper.changeDirection();
46319  }
46320
46321  Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["e" /* extend */])(swiper.params, breakpointParams);
46322  var isEnabled = swiper.params.enabled;
46323  Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["e" /* extend */])(swiper, {
46324    allowTouchMove: swiper.params.allowTouchMove,
46325    allowSlideNext: swiper.params.allowSlideNext,
46326    allowSlidePrev: swiper.params.allowSlidePrev
46327  });
46328
46329  if (wasEnabled && !isEnabled) {
46330    swiper.disable();
46331  } else if (!wasEnabled && isEnabled) {
46332    swiper.enable();
46333  }
46334
46335  swiper.currentBreakpoint = breakpoint;
46336  swiper.emit('_beforeBreakpoint', breakpointParams);
46337
46338  if (needsReLoop && initialized) {
46339    swiper.loopDestroy();
46340    swiper.loopCreate();
46341    swiper.updateSlides();
46342    swiper.slideTo(activeIndex - loopedSlides + swiper.loopedSlides, 0, false);
46343  }
46344
46345  swiper.emit('breakpoint', breakpointParams);
46346}
46347
46348/***/ }),
46349/* 223 */
46350/***/ (function(module, __webpack_exports__, __webpack_require__) {
46351
46352"use strict";
46353/* harmony export (immutable) */ __webpack_exports__["a"] = getBreakp
46353oint;
46354/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
46355
46356function getBreakpoint(breakpoints, base, containerEl) {
46357  if (base === void 0) {
46358    base = 'window';
46359  }
46360
46361  if (!breakpoints || base === 'container' && !containerEl) return undefined;
46362  var breakpoint = false;
46363  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
46364  var currentHeight = base === 'window' ? window.innerHeight : containerEl.clientHeight;
46365  var points = Object.keys(breakpoints).map(function (point) {
46366    if (typeof point === 'string' && point.indexOf('@') === 0) {
46367      var minRatio = parseFloat(point.substr(1));
46368      var value = currentHeight * minRatio;
46369      return {
46370        value: value,
46371        point: point
46372      };
46373    }
46374
46375    return {
46376      value: point,
46377      point: point
46378    };
46379  });
46380  points.sort(function (a, b) {
46381    return parseInt(a.value, 10) - parseInt(b.value, 10);
46382  });
46383
46384  for (var i = 0; i < points.length; i += 1) {
46385    var _points$i = points[i],
46386        point = _points$i.point,
46387        value = _points$i.value;
46388
46389    if (base === 'window') {
46390      if (window.matchMedia("(min-width: " + value + "px)").matches) {
46391        breakpoint = point;
46392      }
46393    } else if (value <= containerEl.clientWidth) {
46394      breakpoint = point;
46395    }
46396  }
46397
46398  return breakpoint || 'max';
46399}
46400
46401/***/ }),
46402/* 224 */
46403/***/ (function(module, __webpack_exports__, __webpack_require__) {
46404
46405"use strict";
46406/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__addClasses__ = __webpack_require__(225);
46407/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__removeClasses__ = __webpack_require__(226);
46408
46409
46410/* harmony default export */ __webpack_exports__["a"] = ({
46411  addClasses: __WEBPACK_IMPORTED_MODULE_0__addClasses__["a" /* default */],
46412  removeClasses: __WEBPACK_IMPORTED_MODULE_1__removeClasses__["a" /* default */]
46413});
46414
46415/***/ }),
46416/* 225 */
46417/***/ (function(module, __webpack_exports__, __webpack_require__) {
46418
46419"use strict";
46420/* harmony export (immutable) */ __webpack_exports__["a"] = addClasses;
46421function prepareClasses(entries, prefix) {
46422  var resultClasses = [];
46423  entries.forEach(function (item) {
46424    if (typeof item === 'object') {
46425      Object.keys(item).forEach(function (classNames) {
46426        if (item[classNames]) {
46427          resultClasses.push(prefix + classNames);
46428        }
46429      });
46430    } else if (typeof item === 'string') {
46431      resultClasses.push(prefix + item);
46432    }
46433  });
46434  return resultClasses;
46435}
46436
46437function addClasses() {
46438  var swiper = this;
46439  var classNames = swiper.classNames,
46440      params = swiper.params,
46441      rtl = swiper.rtl,
46442      $el = swiper.$el,
46443      device = swiper.device,
46444      support = swiper.support; // prettier-ignore
46445
46446  var suffixes = prepareClasses(['initialized', params.direction, {
46447    'pointer-events': support.pointerEvents && !support.touch
46448  }, {
46449    'free-mode': params.freeMode
46450  }, {
46451    'autoheight': params.autoHeight
46452  }, {
46453    'rtl': rtl
46454  }, {
46455    'multirow': params.slidesPerColumn > 1
46456  }, {
46457    'multirow-column': params.slidesPerColumn > 1 && params.slidesPerColumnFill === 'column'
46458  }, {
46459    'android': device.android
46460  }, {
46461    'ios': device.ios
46462  }, {
46463    'css-mode': params.cssMode
46464  }], params.containerModifierClass);
46465  classNames.push.apply(classNames, suffixes);
46466  $el.addClass([].concat(classNames).join(' '));
46467  swiper.emitContainerClasses();
46468}
46469
46470/***/ }),
46471/* 226 */
46472/***/ (function(module, __webpack_exports__, __webpack_require__) {
46473
46474"use strict";
46475/* harmony export (immutable) */ __webpack_exports__["a"] = removeClasses;
46476function removeClasses() {
46477  var swiper = this;
46478  var $el = swiper.$el,
46479      classNames = swiper.classNames;
46480  $el.removeClass(classNames.join(' '));
46481  swiper.emitContainerClasses();
46482}
46483
46484/***/ }),
46485/* 227 */
46486/***/ (function(module, __webpack_exports__, __webpack_require__) {
46487
46488"use strict";
46489/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__loadImage__ = __webpack_require__(228);
46490/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__preloadImages__ = __webpack_require__(229);
46491
46492
46493/* harmony default export */ __webpack_exports__["a"] = ({
46494  loadImage: __WEBPACK_IMPORTED_MODULE_0__loadImage__["a" /* default */],
46495  preloadImages: __WEBPACK_IMPORTED_MODULE_1__preloadImages__["a" /* default */]
46496});
46497
46498/***/ }),
46499/* 228 */
46500/***/ (function(module, __webpack_exports__, __webpack_require__) {
46501
46502"use strict";
46503/* harmony export (immutable) */ __webpack_exports__["a"] = loadImage;
46504/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
46505/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_dom__ = __webpack_require__(3);
46506
46507
46508function loadImage(imageEl, src, srcset, sizes, checkForComplete, callback) {
46509  var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
46510  var image;
46511
46512  function onReady() {
46513    if (callback) callback();
46514  }
46515
46516  var isPicture = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(imageEl).parent('picture')[0];
46517
46518  if (!isPicture && (!imageEl.complete || !checkForComplete)) {
46519    if (src) {
46520      image = new window.Image();
46521      image.onload = onReady;
46522      image.onerror = onReady;
46523
46524      if (sizes) {
46525        image.sizes = sizes;
46526      }
46527
46528      if (srcset) {
46529        image.srcset = srcset;
46530      }
46531
46532      if (src) {
46533        image.src = src;
46534      }
46535    } else {
46536      onReady();
46537    }
46538  } else {
46539    // image already loaded...
46540    onReady();
46541  }
46542}
46543
46544/***/ }),
46545/* 229 */
46546/***/ (function(module, __webpack_exports__, __webpack_require__) {
46547
46548"use strict";
46549/* harmony export (immutable) */ __webpack_exports__["a"] = preloadImages;
46550function preloadImages() {
46551  var swiper = this;
46552  swiper.imagesToLoad = swiper.$el.find('img');
46553
46554  function onReady() {
46555    if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper.destroyed) return;
46556    if (swiper.imagesLoaded !== undefined) swiper.imagesLoaded += 1;
46557
46558    if (swiper.imagesLoaded === swiper.imagesToLoad.length) {
46559      if (swiper.params.updateOnImagesReady) swiper.update();
46560      swiper.emit('imagesReady');
46561    }
46562  }
46563
46564  for (var i = 0; i < swiper.imagesToLoad.length; i += 1) {
46565    var imageEl = swiper.imagesToLoad[i];
46566    swiper.loadImage(imageEl, imageEl.currentSrc || imageEl.getAttribute('src'), imageEl.srcset || imageEl.getAttribute('srcset'), imageEl.sizes || imageEl.getAttribute('sizes'), true, onReady);
46567  }
46568}
46569
46570/***/ }),
46571/* 230 */
46572/***/ (function(module, __webpack_exports__, __webpack_require__) {
46573
46574"use strict";
46575function checkOverflow() {
46576  var swiper = this;
46577  var params = swiper.params;
46578  var wasLocked = swiper.isLocked;
46579  var lastSlidePosition = swiper.slides.length > 0 && params.slidesOffsetBefore + params.spaceBetween * (swiper.slides.length - 1) + swiper.slides[0].offsetWidth * swiper.slides.length;
46580
46581  if (params.slidesOffsetBefore && params.slidesOffsetAfter && lastSlidePosition) {
46582    swiper.isLocked = lastSlidePosition <= swiper.size;
46583  } else {
46584    swiper.isLocked = swiper.snapGrid.length === 1;
46585  }
46586
46587  swiper.allowSlideNext = !swiper.isLocked;
46588  swiper.allowSlidePrev = !swiper.isLocked; // events
46589
46590  if (wasLocked !== swiper.isLocked) swiper.emit(swiper.isLocked ? 'lock' : 'unlock');
46591
46592  if (wasLocked && wasLocked !== swiper.isLocked) {
46593    swiper.isEnd = false;
46594    if (swiper.navigation) swiper.navigation.update();
46595  }
46596}
46597
46598/* harmony default export */ __webpack_exports__["a"] = ({
46599  checkOverflow: checkOverflow
46600});
46601
46602/***/ }),
46603/* 231 */
46604/***/ (function(module, __webpack_exports__, __webpack_require__) {
46605
46606"use strict";
46607/* harmony default export */ __webpack_exports__["a"] = ({
46608  init: true,
46609  direction: 'horizontal',
46610  touchEventsTarget: 'container',
46611  initialSlide: 0,
46612  speed: 300,
46613  cssMode: false,
46614  updateOnWindowResize: true,
46615  resizeObserver: false,
46616  nested: false,
46617  createElements: false,
46618  enabled: true,
46619  focusableElements: 'input, select, option, textarea, button, video, label',
46620  // Overrides
46621  width: null,
46622  height: null,
46623  //
46624  preventInteractionOnTransition: false,
46625  // ssr
46626  userAgent: null,
46627  url: null,
46628  // To support iOS's swipe-to-go-back gesture (when being used in-app).
46629  edgeSwipeDetection: false,
46630  edgeSwipeThreshold: 20,
46631  // Free mode
46632  freeMode: false,
46633  freeModeMomentum: true,
46634  freeModeMomentumRatio: 1,
46635  freeModeMomentumBounce: true,
46636  freeModeMomentumBounceRatio: 1,
46637  freeModeMomentumVelocityRatio: 1,
46638  freeModeSticky: false,
46639  freeModeMinimumVelocity: 0.02,
46640  // Autoheight
46641  autoHeight: false,
46642  // Set wrapper width
46643  setWrapperSize: false,
46644  // Virtual Translate
46645  virtualTranslate: false,
46646  // Effects
46647  effect: 'slide',
46648  // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
46649  // Breakpoints
46650  breakpoints: undefined,
46651  breakpointsBase: 'window',
46652  // Slides grid
46653  spaceBetween: 0,
46654  slidesPerView: 1,
46655  slidesPerColumn: 1,
46656  slidesPerColumnFill: 'column',
46657  slidesPerGroup: 1,
46658  slidesPerGroupSkip: 0,
46659  centeredSlides: false,
46660  centeredSlidesBounds: false,
46661  slidesOffsetBefore: 0,
46662  // in px
46663  slidesOffsetAfter: 0,
46664  // in px
46665  normalizeSlideIndex: true,
46666  centerInsufficientSlides: false,
46667  // Disable swiper and hide navigation when container not overflow
46668  watchOverflow: false,
46669  // Round length
46670  roundLengths: false,
46671  // Touches
46672  touchRatio: 1,
46673  touchAngle: 45,
46674  simulateTouch: true,
46675  shortSwipes: true,
46676  longSwipes: true,
46677  longSwipesRatio: 0.5,
46678  longSwipesMs: 300,
46679  followFinger: true,
46680  allowTouchMove: true,
46681  threshold: 0,
46682  touchMoveStopPropagation: false,
46683  touchStartPreventDefault: true,
46684  touchStartForcePreventDefault: false,
46685  touchReleaseOnEdges: false,
46686  // Unique Navigation Elements
46687  uniqueNavElements: true,
46688  // Resistance
46689  resistance: true,
46690  resistanceRatio: 0.85,
46691  // Progress
46692  watchSlidesProgress: false,
46693  watchSlidesVisibility: false,
46694  // Cursor
46695  grabCursor: false,
46696  // Clicks
46697  preventClicks: true,
46698  preventClicksPropagation: true,
46699  slideToClickedSlide: false,
46700  // Images
46701  preloadImages: true,
46702  updateOnImagesReady: true,
46703  // loop
46704  loop: false,
46705  loopAdditionalSlides: 0,
46706  loopedSlides: null,
46707  loopFillGroupWithBlank: false,
46708  loopPreventsSlide: true,
46709  // Swiping/no swiping
46710  allowSlidePrev: true,
46711  allowSlideNext: true,
46712  swipeHandler: null,
46713  // '.swipe-handler',
46714  noSwiping: true,
46715  noSwipingClass: 'swiper-no-swiping',
46716  noSwipingSelector: null,
46717  // Passive Listeners
46718  passiveListeners: true,
46719  // NS
46720  containerModifierClass: 'swiper-container-',
46721  // NEW
46722  slideClass: 'swiper-slide',
46723  slideBlankClass: 'swiper-slide-invisible-blank',
46724  slideActiveClass: 'swiper-slide-active',
46725  slideDuplicateActiveClass: 'swiper-slide-duplicate-active',
46726  slideVisibleClass: 'swiper-slide-visible',
46727  slideDuplicateClass: 'swiper-slide-duplicate',
46728  slideNextClass: 'swiper-slide-next',
46729  slideDuplicateNextClass: 'swiper-slide-duplicate-next',
46730  slidePrevClass: 'swiper-slide-prev',
46731  slideDuplicatePrevClass: 'swiper-slide-duplicate-prev',
46732  wrapperClass: 'swiper-wrapper',
46733  // Callbacks
46734  runCallbacksOnInit: true,
46735  // Internals
46736  _emitClasses: false
46737});
46738
46739/***/ }),
46740/* 232 */
46741/***/ (function(module, __webpack_exports__, __webpack_require__) {
46742
46743"use strict";
46744/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_dom__ = __webpack_require__(3);
46745/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
46746function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
46747
46748
46749
46750var Virtual = {
46751  update: function update(force) {
46752    var swiper = this;
46753    var _swiper$params = swiper.params,
46754        slidesPerView = _swiper$params.slidesPerView,
46755        slidesPerGroup = _swiper$params.slidesPerGroup,
46756        centeredSlides = _swiper$params.centeredSlides;
46757    var _swiper$params$virtua = swiper.params.virtual,
46758        addSlidesBefore = _swiper$params$virtua.addSlidesBefore,
46759        addSlidesAfter = _swiper$params$virtua.addSlidesAfter;
46760    var _swiper$virtual = swiper.virtual,
46761        previousFrom = _swiper$virtual.from,
46762        previousTo = _swiper$virtual.to,
46763        slides = _swiper$virtual.slides,
46764        previousSlidesGrid = _swiper$virtual.slidesGrid,
46765        renderSlide = _swiper$virtual.renderSlide,
46766        previousOffset = _swiper$virtual.offset;
46767    swiper.updateActiveIndex();
46768    var activeIndex = swiper.activeIndex || 0;
46769    var offsetProp;
46770    if (swiper.rtlTranslate) offsetProp = 'right';else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
46771    var slidesAfter;
46772    var slidesBefore;
46773
46774    if (centeredSlides) {
46775      slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;
46776      slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;
46777    } else {
46778      slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter;
46779      slidesBefore = slidesPerGroup + addSlidesBefore;
46780    }
46781
46782    var from = Math.max((activeIndex || 0) - slidesBefore, 0);
46783    var to = Math.min((activeIndex || 0) + slidesAfter, slides.length - 1);
46784    var offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
46785    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["e" /* extend */])(swiper.virtual, {
46786      from: from,
46787      to: to,
46788      offset: offset,
46789      slidesGrid: swiper.slidesGrid
46790    });
46791
46792    function onRendered() {
46793      swiper.updateSlides();
46794      swiper.updateProgress();
46795      swiper.updateSlidesClasses();
46796
46797      if (swiper.lazy && swiper.params.lazy.enabled) {
46798        swiper.lazy.load();
46799      }
46800    }
46801
46802    if (previousFrom === from && previousTo === to && !force) {
46803      if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
46804        swiper.slides.css(offsetProp, offset + "px");
46805      }
46806
46807      swiper.updateProgress();
46808      return;
46809    }
46810
46811    if (swiper.params.virtual.renderExternal) {
46812      swiper.params.virtual.renderExternal.call(swiper, {
46813        offset: offset,
46814        from: from,
46815        to: to,
46816        slides: function getSlides() {
46817          var slidesToRender = [];
46818
46819          for (var i = from; i <= to; i += 1) {
46820            slidesToRender.push(slides[i]);
46821          }
46822
46823          return slidesToRender;
46824        }()
46825      });
46826
46827      if (swiper.params.virtual.renderExternalUpdate) {
46828        onRendered();
46829      }
46830
46831      return;
46832    }
46833
46834    var prependIndexes = [];
46835    var appendIndexes = [];
46836
46837    if (force) {
46838      swiper.$wrapperEl.find("." + swiper.params.slideClass).remove();
46839    } else {
46840      for (var i = previousFrom; i <= previousTo; i += 1) {
46841        if (i < from || i > to) {
46842          swiper.$wrapperEl.find("." + swiper.params.slideClass + "[data-swiper-slide-index=\"" + i + "\"]").remove();
46843        }
46844      }
46845    }
46846
46847    for (var _i = 0; _i < slides.length; _i += 1) {
46848      if (_i >= from && _i <= to) {
46849        if (typeof previousTo === 'undefined' || force) {
46850          appendIndexes.push(_i);
46851        } else {
46852          if (_i > previousTo) appendIndexes.push(_i);
46853          if (_i < previousFrom) prependIndexes.push(_i);
46854        }
46855      }
46856    }
46857
46858    appendIndexes.forEach(function (index) {
46859      swiper.$wrapperEl.append(renderSlide(slides[index], index));
46860    });
46861    prependIndexes.sort(function (a, b) {
46862      return b - a;
46863    }
46863).forEach(function (index) {
46864      swiper.$wrapperEl.prepend(renderSlide(slides[index], index));
46865    });
46866    swiper.$wrapperEl.children('.swiper-slide').css(offsetProp, offset + "px");
46867    onRendered();
46868  },
46869  renderSlide: function renderSlide(slide, index) {
46870    var swiper = this;
46871    var params = swiper.params.virtual;
46872
46873    if (params.cache && swiper.virtual.cache[index]) {
46874      return swiper.virtual.cache[index];
46875    }
46876
46877    var $slideEl = params.renderSlide ? Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(params.renderSlide.call(swiper, slide, index)) : Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])("<div class=\"" + swiper.params.slideClass + "\" data-swiper-slide-index=\"" + index + "\">" + slide + "</div>");
46878    if (!$slideEl.attr('data-swiper-slide-index')) $slideEl.attr('data-swiper-slide-index', index);
46879    if (params.cache) swiper.virtual.cache[index] = $slideEl;
46880    return $slideEl;
46881  },
46882  appendSlide: function appendSlide(slides) {
46883    var swiper = this;
46884
46885    if (typeof slides === 'object' && 'length' in slides) {
46886      for (var i = 0; i < slides.length; i += 1) {
46887        if (slides[i]) swiper.virtual.slides.push(slides[i]);
46888      }
46889    } else {
46890      swiper.virtual.slides.push(slides);
46891    }
46892
46893    swiper.virtual.update(true);
46894  },
46895  prependSlide: function prependSlide(slides) {
46896    var swiper = this;
46897    var activeIndex = swiper.activeIndex;
46898    var newActiveIndex = activeIndex + 1;
46899    var numberOfNewSlides = 1;
46900
46901    if (Array.isArray(slides)) {
46902      for (var i = 0; i < slides.length; i += 1) {
46903        if (slides[i]) swiper.virtual.slides.unshift(slides[i]);
46904      }
46905
46906      newActiveIndex = activeIndex + slides.length;
46907      numberOfNewSlides = slides.length;
46908    } else {
46909      swiper.virtual.slides.unshift(slides);
46910    }
46911
46912    if (swiper.params.virtual.cache) {
46913      var cache = swiper.virtual.cache;
46914      var newCache = {};
46915      Object.keys(cache).forEach(function (cachedIndex) {
46916        var $cachedEl = cache[cachedIndex];
46917        var cachedElIndex = $cachedEl.attr('data-swiper-slide-index');
46918
46919        if (cachedElIndex) {
46920          $cachedEl.attr('data-swiper-slide-index', parseInt(cachedElIndex, 10) + 1);
46921        }
46922
46923        newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = $cachedEl;
46924      });
46925      swiper.virtual.cache = newCache;
46926    }
46927
46928    swiper.virtual.update(true);
46929    swiper.slideTo(newActiveIndex, 0);
46930  },
46931  removeSlide: function removeSlide(slidesIndexes) {
46932    var swiper = this;
46933    if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;
46934    var activeIndex = swiper.activeIndex;
46935
46936    if (Array.isArray(slidesIndexes)) {
46937      for (var i = slidesIndexes.length - 1; i >= 0; i -= 1) {
46938        swiper.virtual.slides.splice(slidesIndexes[i], 1);
46939
46940        if (swiper.params.virtual.cache) {
46941          delete swiper.virtual.cache[slidesIndexes[i]];
46942        }
46943
46944        if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
46945        activeIndex = Math.max(activeIndex, 0);
46946      }
46947    } else {
46948      swiper.virtual.slides.splice(slidesIndexes, 1);
46949
46950      if (swiper.params.virtual.cache) {
46951        delete swiper.virtual.cache[slidesIndexes];
46952      }
46953
46954      if (slidesIndexes < activeIndex) activeIndex -= 1;
46955      activeIndex = Math.max(activeIndex, 0);
46956    }
46957
46958    swiper.virtual.update(true);
46959    swiper.slideTo(activeIndex, 0);
46960  },
46961  removeAllSlides: function removeAllSlides() {
46962    var swiper = this;
46963    swiper.virtual.slides = [];
46964
46965    if (swiper.params.virtual.cache) {
46966      swiper.virtual.cache = {};
46967    }
46968
46969    swiper.virtual.update(true);
46970    swiper.slideTo(0, 0);
46971  }
46972};
46973/* harmony default export */ __webpack_exports__["a"] = ({
46974  name: 'virtual',
46975  params: {
46976    virtual: {
46977      enabled: false,
46978      slides: [],
46979      cache: true,
46980      renderSlide: null,
46981      renderExternal: null,
46982      renderExternalUpdate: true,
46983      addSlidesBefore: 0,
46984      addSlidesAfter: 0
46985    }
46986  },
46987  create: function create() {
46988    var swiper = this;
46989    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["a" /* bindModuleMethods */])(swiper, {
46990      virtual: _extends({}, Virtual, {
46991        slides: swiper.params.virtual.slides,
46992        cache: {}
46993      })
46994    });
46995  },
46996  on: {
46997    beforeInit: function beforeInit(swiper) {
46998      if (!swiper.params.virtual.enabled) return;
46999      swiper.classNames.push(swiper.params.containerModifierClass + "virtual");
47000      var overwriteParams = {
47001        watchSlidesProgress: true
47002      };
47003      Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["e" /* extend */])(swiper.params, overwriteParams);
47004      Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["e" /* extend */])(swiper.originalParams, overwriteParams);
47005
47006      if (!swiper.params.initialSlide) {
47007        swiper.virtual.update();
47008      }
47009    },
47010    setTranslate: function setTranslate(swiper) {
47011      if (!swiper.params.virtual.enabled) return;
47012      swiper.virtual.update();
47013    }
47014  }
47015});
47016
47017/***/ }),
47018/* 233 */
47019/***/ (function(module, __webpack_exports__, __webpack_require__) {
47020
47021"use strict";
47022/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
47023/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_dom__ = __webpack_require__(3);
47024/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_utils__ = __webpack_require__(1);
47025function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
47026
47027/* eslint-disable consistent-return */
47028
47029
47030
47031var Keyboard = {
47032  handle: function handle(event) {
47033    var swiper = this;
47034    if (!swiper.enabled) return;
47035    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
47036    var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
47037    var rtl = swiper.rtlTranslate;
47038    var e = event;
47039    if (e.originalEvent) e = e.originalEvent; // jquery fix
47040
47041    var kc = e.keyCode || e.charCode;
47042    var pageUpDown = swiper.params.keyboard.pageUpDown;
47043    var isPageUp = pageUpDown && kc === 33;
47044    var isPageDown = pageUpDown && kc === 34;
47045    var isArrowLeft = kc === 37;
47046    var isArrowRight = kc === 39;
47047    var isArrowUp = kc === 38;
47048    var isArrowDown = kc === 40; // Directions locks
47049
47050    if (!swiper.allowSlideNext && (swiper.isHorizontal() && isArrowRight || swiper.isVertical() && isArrowDown || isPageDown)) {
47051      return false;
47052    }
47053
47054    if (!swiper.allowSlidePrev && (swiper.isHorizontal() && isArrowLeft || swiper.isVertical() && isArrowUp || isPageUp)) {
47055      return false;
47056    }
47057
47058    if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
47059      return undefined;
47060    }
47061
47062    if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {
47063      return undefined;
47064    }
47065
47066    if (swiper.params.keyboard.onlyInViewport && (isPageUp || isPageDown || isArrowLeft || isArrowRight || isArrowUp || isArrowDown)) {
47067      var inView = false; // Check that swiper should be inside of visible area of window
47068
47069      if (swiper.$el.parents("." + swiper.params.slideClass).length > 0 && swiper.$el.parents("." + swiper.params.slideActiveClass).length === 0) {
47070        return undefined;
47071      }
47072
47073      var $el = swiper.$el;
47074      var swiperWidth = $el[0].clientWidth;
47075      var swiperHeight = $el[0].clientHeight;
47076      var windowWidth = window.innerWidth;
47077      var windowHeight = window.innerHeight;
47078      var swiperOffset = swiper.$el.offset();
47079      if (rtl) swiperOffset.left -= swiper.$el[0].scrollLeft;
47080      var swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiperWidth, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiperHeight], [swiperOffset.left + swiperWidth, swiperOffset.top + swiperHeight]];
47081
47082      for (var i = 0; i < swiperCoord.length; i += 1) {
47083        var point = swiperCoord[i];
47084
47085        if (point[0] >= 0 && point[0] <= windowWidth && point[1] >= 0 && point[1] <= windowHeight) {
47086          if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line
47087
47088          inView = true;
47089        }
47090      }
47091
47092      if (!inView) return undefined;
47093    }
47094
47095    if (swiper.isHorizontal()) {
47096      if (isPageUp || isPageDown || isArrowLeft || isArrowRight) {
47097        if (e.preventDefault) e.preventDefault();else e.returnValue = false;
47098      }
47099
47100      if ((isPageDown || isArrowRight) && !rtl || (isPageUp || isArrowLeft) && rtl) swiper.slideNext();
47101      if ((isPageUp || isArrowLeft) && !rtl || (isPageDown || isArrowRight) && rtl) swiper.slidePrev();
47102    } else {
47103      if (isPageUp || isPageDown || isArrowUp || isArrowDown) {
47104        if (e.preventDefault) e.preventDefault();else e.returnValue = false;
47105      }
47106
47107      if (isPageDown || isArrowDown) swiper.slideNext();
47108      if (isPageUp || isArrowUp) swiper.slidePrev();
47109    }
47110
47111    swiper.emit('keyPress', kc);
47112    return undefined;
47113  },
47114  enable: function enable() {
47115    var swiper = this;
47116    var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
47117    if (swiper.keyboard.enabled) return;
47118    Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(document).on('keydown', swiper.keyboard.handle);
47119    swiper.keyboard.enabled = true;
47120  },
47121  disable: function disable() {
47122    var swiper = this;
47123    var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
47124    if (!swiper.keyboard.enabled) return;
47125    Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(document).off('keydown', swiper.keyboard.handle);
47126    swiper.keyboard.enabled = false;
47127  }
47128};
47129/* harmony default export */ __webpack_exports__["a"] = ({
47130  name: 'keyboard',
47131  params: {
47132    keyboard: {
47133      enabled: false,
47134      onlyInViewport: true,
47135      pageUpDown: true
47136    }
47137  },
47138  create: function create() {
47139    var swiper = this;
47140    Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["a" /* bindModuleMethods */])(swiper, {
47141      keyboard: _extends({
47142        enabled: false
47143      }, Keyboard)
47144    });
47145  },
47146  on: {
47147    init: function init(swiper) {
47148      if (swiper.params.keyboard.enabled) {
47149        swiper.keyboard.enable();
47150      }
47151    },
47152    destroy: function destroy(swiper) {
47153      if (swiper.keyboard.enabled) {
47154        swiper.keyboard.disable();
47155      }
47156    }
47157  }
47158});
47159
47160/***/ }),
47161/* 234 */
47162/***/ (function(module, __webpack_exports__, __webpack_require__) {
47163
47164"use strict";
47165/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
47166/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_dom__ = __webpack_require__(3);
47167/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_utils__ = __webpack_require__(1);
47168/* eslint-disable consistent-return */
47169
47170
47171
47172
47173function isEventSupported() {
47174  var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
47175  var eventName = 'onwheel';
47176  var isSupported = (eventName in document);
47177
47178  if (!isSupported) {
47179    var element = document.createElement('div');
47180    element.setAttribute(eventName, 'return;');
47181    isSupported = typeof element[eventName] === 'function';
47182  }
47183
47184  if (!isSupported && document.implementation && document.implementation.hasFeature && // always returns true in newer browsers as per the standard.
47185  // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
47186  document.implementation.hasFeature('', '') !== true) {
47187    // This is the only way to test support for the `wheel` event in IE9+.
47188    isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
47189  }
47190
47191  return isSupported;
47192}
47193
47194var Mousewheel = {
47195  lastScrollTime: Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["i" /* now */])(),
47196  lastEventBeforeSnap: undefined,
47197  recentWheelEvents: [],
47198  event: function event() {
47199    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
47200    if (window.navigator.userAgent.indexOf('firefox') > -1) return 'DOMMouseScroll';
47201    return isEventSupported() ? 'wheel' : 'mousewheel';
47202  },
47203  normalize: function normalize(e) {
47204    // Reasonable defaults
47205    var PIXEL_STEP = 10;
47206    var LINE_HEIGHT = 40;
47207    var PAGE_HEIGHT = 800;
47208    var sX = 0;
47209    var sY = 0; // spinX, spinY
47210
47211    var pX = 0;
47212    var pY = 0; // pixelX, pixelY
47213    // Legacy
47214
47215    if ('detail' in e) {
47216      sY = e.detail;
47217    }
47218
47219    if ('wheelDelta' in e) {
47220      sY = -e.wheelDelta / 120;
47221    }
47222
47223    if ('wheelDeltaY' in e) {
47224      sY = -e.wheelDeltaY / 120;
47225    }
47226
47227    if ('wheelDeltaX' in e) {
47228      sX = -e.wheelDeltaX / 120;
47229    } // side scrolling on FF with DOMMouseScroll
47230
47231
47232    if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {
47233      sX = sY;
47234      sY = 0;
47235    }
47236
47237    pX = sX * PIXEL_STEP;
47238    pY = sY * PIXEL_STEP;
47239
47240    if ('deltaY' in e) {
47241      pY = e.deltaY;
47242    }
47243
47244    if ('deltaX' in e) {
47245      pX = e.deltaX;
47246    }
47247
47248    if (e.shiftKey && !pX) {
47249      // if user scrolls with shift he wants horizontal scroll
47250      pX = pY;
47251      pY = 0;
47252    }
47253
47254    if ((pX || pY) && e.deltaMode) {
47255      if (e.deltaMode === 1) {
47256        // delta in LINE units
47257        pX *= LINE_HEIGHT;
47258        pY *= LINE_HEIGHT;
47259      } else {
47260        // delta in PAGE units
47261        pX *= PAGE_HEIGHT;
47262        pY *= PAGE_HEIGHT;
47263      }
47264    } // Fall-back if spin cannot be determined
47265
47266
47267    if (pX && !sX) {
47268      sX = pX < 1 ? -1 : 1;
47269    }
47270
47271    if (pY && !sY) {
47272      sY = pY < 1 ? -1 : 1;
47273    }
47274
47275    return {
47276      spinX: sX,
47277      spinY: sY,
47278      pixelX: pX,
47279      pixelY: pY
47280    };
47281  },
47282  handleMouseEnter: function handleMouseEnter() {
47283    var swiper = this;
47284    if (!swiper.enabled) return;
47285    swiper.mouseEntered = true;
47286  },
47287  handleMouseLeave: function handleMouseLeave() {
47288    var swiper = this;
47289    if (!swiper.enabled) return;
47290    swiper.mouseEntered = false;
47291  },
47292  handle: function handle(event) {
47293    var e = event;
47294    var disableParentSwiper = true;
47295    var swiper = this;
47296    if (!swiper.enabled) return;
47297    var params = swiper.params.mousewheel;
47298
47299    if (swiper.params.cssMode) {
47300      e.preventDefault();
47301    }
47302
47303    var target = swiper.$el;
47304
47305    if (swiper.params.mousewheel.eventsTarget !== 'container') {
47306      target = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(swiper.params.mousewheel.eventsTarget);
47307    }
47308
47309    if (!swiper.mouseEntered && !target[0].contains(e.target) && !params.releaseOnEdges) return true;
47310    if (e.originalEvent) e = e.originalEvent; // jquery fix
47311
47312    var delta = 0;
47313    var rtlFactor = swiper.rtlTranslate ? -1 : 1;
47314    var data = Mousewheel.normalize(e);
47315
47316    if (params.forceToAxis) {
47317      if (swiper.isHorizontal()) {
47318        if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = -data.pixelX * rtlFactor;else return true;
47319      } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = -data.pixelY;else return true;
47320    } else {
47321      delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;
47322    }
47323
47324    if (delta === 0) return true;
47325    if (params.invert) delta = -delta; // Get the scroll positions
47326
47327    var positions = swiper.getTranslate() + delta * params.sensitivity;
47328    if (positions >= swiper.minTranslate()) positions = swiper.minTranslate();
47329    if (positions <= swiper.maxTranslate()) positions = swiper.maxTranslate(); // When loop is true:
47330    //     the disableParentSwiper will be true.
47331    // When loop is false:
47332    //     if the scroll positions is not on edge,
47333    //     then the disableParentSwiper will be true.
47334    //     if the scroll on edge positions,
47335    //     then the disableParentSwiper will be false.
47336
47337    disableParentSwiper = swiper.params.loop ? true : !(positions === swiper.minTranslate() || positions === swiper.maxTranslate());
47338    if (disableParentSwiper && swiper.params.nested) e.stopPropagation();
47339
47340    if (!swiper.params.freeMode) {
47341      // Register the new event in a variable which stores the relevant data
47342      var newEvent = {
47343        time: Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["i" /* now */])(),
47344        delta: Math.abs(delta),
47345        direction: Math.sign(delta),
47346        raw: event
47347      }; // Keep the most recent events
47348
47349      var recentWheelEvents = swiper.mousewheel.recentWheelEvents;
47350
47351      if (recentWheelEvents.length >= 2) {
47352        recentWheelEvents.shift(); // only store the last N events
47353      }
47354
47355      var prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
47356      recentWheelEvents.push(newEvent); // If there is at least one previous recorded event:
47357      //   If direction has changed or
47358      //   if the scroll is quicker than the previous one:
47359      //     Animate the slider.
47360      // Else (this is the first time the wheel is moved):
47361      //     Animate the slider.
47362
47363      if (prevEvent) {
47364        if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) {
47365          swiper.mousewheel.animateSlider(newEvent);
47366        }
47367      } else {
47368        swiper.mousewheel.animateSlider(newEvent);
47369      } // If it's time to release the scroll:
47370      //   Return now so you don't hit the preventDefault.
47371
47372
47373      if (swiper.mousewheel.releaseScroll(newEvent)) {
47374        return true;
47375      }
47376    } else {
47377      // Freemode or scrollContainer:
47378      // If we recently snapped after a momentum scroll, then ignore wheel events
47379      // to give time for the deceleration to finish. Stop ignoring after 500 msecs
47380      // or if it's a new scroll (larger delta or inverse sign as last event before
47381      // an end-of-momentum snap).
47382      var _newEvent = {
47383        time: Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["i" /* now */])(),
47384        delta: Math.abs(delta),
47385        direction: Math.sign(delta)
47386      };
47387      var lastEventBeforeSnap = swiper.mousewheel.lastEventBeforeSnap;
47388      var ignoreWheelEvents = lastEventBeforeSnap && _newEvent.time < lastEventBeforeSnap.time + 500 && _newEvent.delta <= lastEventBeforeSnap.delta && _newEvent.direction === lastEventBeforeSnap.direction;
47389
47390      if (!ignoreWheelEvents) {
47391        swiper.mousewheel.lastEventBeforeSnap = undefined;
47392
47393        if (swiper.params.loop) {
47394          swiper.loopFix();
47395        }
47396
47397        var position = swiper.getTranslate() + delta * params.sensitivity;
47398        var wasBeginning = swiper.isBeginning;
47399        var wasEnd = swiper.isEnd;
47400        if (position >= swiper.minTranslate()) position = swiper.minTranslate();
47401        if (position <= swiper.maxTranslate()) position = swiper.maxTranslate();
47402        swiper.setTransition(0);
47403        swiper.setTranslate(position);
47404        swiper.updateProgress();
47405        swiper.updateActiveIndex();
47406        swiper.updateSlidesClasses();
47407
47408        if (!wasBeginning && swiper.isBeginning || !wasEnd && swiper.isEnd) {
47409          swiper.updateSlidesClasses();
47410        }
47411
47412        if (swiper.params.freeModeSticky) {
47413          // When wheel scrolling starts with sticky (aka snap) enabled, then detect
47414          // the end of a momentum scroll by storing recent (N=15?) wheel events.
47415          // 1. do all N events have decreasing or same (absolute value) delta?
47416          // 2. did all N events arrive in the last M (M=500?) msecs?
47417          // 3. does the earliest event have an (absolute value) delta that's
47418          //    at least P (P=1?) larger than the most recent event's delta?
47419          // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels?
47420          // If 1-4 are "yes" then we're near the end of a momentum scroll deceleration.
47421          // Snap immediately and ignore remaining wheel events in this scroll.
47422          // See comment above for "remaining wheel events in this scroll" determination.
47423          // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event.
47424          clearTimeout(swiper.mousewheel.timeout);
47425          swiper.mousewheel.timeout = undefined;
47426          var _recentWheelEvents = swiper.mousewheel.recentWheelEvents;
47427
47428          if (_recentWheelEvents.length >= 15) {
47429            _recentWheelEvents.shift(); // only store the last N events
47430
47431          }
47432
47433          var _prevEvent = _recentWheelEvents.length ? _recentWheelEvents[_recentWheelEvents.length - 1] : undefined;
47434
47435          var firstEvent = _recentWheelEvents[0];
47436
47437          _recentWheelEvents.push(_newEvent);
47438
47439          if (_prevEvent && (_newEvent.delta > _prevEvent.delta || _newEvent.direction !== _prevEvent.direction)) {
47440            // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log.
47441            _recentWheelEvents.splice(0);
47442          } else if (_recentWheelEvents.length >= 15 && _newEvent.time - firstEvent.time < 500 && firstEvent.delta - _newEvent.delta >= 1 && _newEvent.delta <= 6) {
47443            // We're at the end of the deceleration of a momentum scroll, so there's no need
47444            // to wait for more events. Snap ASAP on the next tick.
47445            // Also, because there's some remaining momentum we'll bias the snap in the
47446            // direction of the ongoing scroll because it's better UX for the scroll to snap
47447            // in the same direction as the scroll instead of reversing to snap.  Therefore,
47448            // if it's already scrolled more than 20% in the current direction, keep going.
47449            var snapToThreshold = delta > 0 ? 0.8 : 0.2;
47450            swiper.mousewheel.lastEventBeforeSnap = _newEvent;
47451
47452            _recentWheelEvents.splice(0);
47453
47454            swiper.mousewheel.timeout = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["h" /* nextTick */])(function () {
47455              swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
47456            }, 0); // no delay; move on next tick
47457          }
47458
47459          if (!swiper.mousewheel.timeout) {
47460            // if we get here, then we haven't detected the end of a momentum scroll, so
47461            // we'll consider a scroll "complete" when there haven't been any wheel events
47462            // for 500ms.
47463            swiper.mousewheel.timeout = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["h" /* nextTick */])(function () {
47464              var snapToThreshold = 0.5;
47465              swiper.mousewheel.lastEventBeforeSnap = _newEvent;
47466
47467              _recentWheelEvents.splice(0);
47468
47469              swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
47470            }, 500);
47471          }
47472        } // Emit event
47473
47474
47475        if (!ignoreWheelEvents) swiper.emit('scroll', e); // Stop autoplay
47476
47477        if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) swiper.autoplay.stop(); // Return page scroll on edge positions
47478
47479        if (position === swiper.minTranslate() || position === swiper.maxTranslate()) return true;
47480      }
47481    }
47482
47483    if (e.preventDefault) e.preventDefault();else e.returnValue = false;
47484    return false;
47485  },
47486  animateSlider: function animateSlider(newEvent) {
47487    var swiper = this;
47488    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
47489
47490    if (this.params.mousewheel.thresholdDelta && newEvent.delta < this.params.mousewheel.thresholdDelta) {
47491      // Prevent if delta of wheel scroll delta is below configured threshold
47492      return false;
47493    }
47494
47495    if (this.params.mousewheel.thresholdTime && Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["i" /* now */])() - swiper.mousewheel.lastScrollTime < this.params.mousewheel.thresholdTime) {
47496      // Prevent if time between scrolls is below configured threshold
47497      return false;
47498    } // If the movement is NOT big enough and
47499    // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider):
47500    //   Don't go any further (avoid insignificant scroll movement).
47501
47502
47503    if (newEvent.delta >= 6 && Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["i" /* now */])() - swiper.mousewheel.lastScrollTime < 60) {
47504      // Return false as a default
47505      return true;
47506    } // If user is scrolling towards the end:
47507    //   If the slider hasn't hit the latest slide or
47508    //   if the slider is a loop and
47509    //   if the slider isn't moving right now:
47510    //     Go to next slide and
47511    //     emit a scroll event.
47512    // Else (the user is scrolling towards the beginning) and
47513    // if the slider hasn't hit the first slide or
47514    // if the slider is a loop and
47515    // if the slider isn't moving right now:
47516    //   Go to prev slide and
47517    //   emit a scroll event.
47518
47519
47520    if (newEvent.direction < 0) {
47521      if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {
47522        swiper.slideNext();
47523        swiper.emit('scroll', newEvent.raw);
47524      }
47525    } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {
47526      swiper.slidePrev();
47527      swiper.emit('scroll', newEvent.raw);
47528    } // If you got here is because an animation has been triggered so store the current time
47529
47530
47531    swiper.mousewheel.lastScrollTime = new window.Date().getTime(); // Return false as a default
47532
47533    return false;
47534  },
47535  releaseScroll: function releaseScroll(newEvent) {
47536    var swiper = this;
47537    var params = swiper.params.mousewheel;
47538
47539    if (newEvent.direction < 0) {
47540      if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) {
47541        // Return true to animate scroll on edges
47542        return true;
47543      }
47544    } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) {
47545      // Return true to animate scroll on edges
47546      return true;
47547    }
47548
47549    return false;
47550  },
47551  enable: function enable() {
47552    var swiper = this;
47553    var event = Mousewheel.event();
47554
47555    if (swiper.params.cssMode) {
47556      swiper.wrapperEl.removeEventListener(event, swiper.mousewheel.handle);
47557      return true;
47558    }
47559
47560    if (!event) return false;
47561    if (swiper.mousewheel.enabled) return false;
47562    var target = swiper.$el;
47563
47564    if (swiper.params.mousewheel.eventsTarget !== 'container') {
47565      target = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(swiper.params.mousewheel.eventsTarget);
47566    }
47567
47568    target.on('mouseenter', swiper.mousewheel.handleMouseEnter);
47569    target.on('mouseleave', swiper.mousewheel.handleMouseLeave);
47570    target.on(event, swiper.mousewheel.handle);
47571    swiper.mousewheel.enabled = true;
47572    return true;
47573  },
47574  disable: function disable() {
47575    var swiper = this;
47576    var event = Mousewheel.event();
47577
47578    if (swiper.params.cssMode) {
47579      swiper.wrapperEl.addEventListener(event, swiper.mousewheel.handle);
47580      return true;
47581    }
47582
47583    if (!event) return false;
47584    if (!swiper.mousewheel.enabled) return false;
47585    var target = swiper.$el;
47586
47587    if (swiper.params.mousewheel.eventsTarget !== 'container') {
47588      target = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(swiper.params.mousewheel.eventsTarget);
47589    }
47590
47591    target.off(event, swiper.mousewheel.handle);
47592    swiper.mousewheel.enabled = false;
47593    return true;
47594  }
47595};
47596/* harmony default export */ __webpack_exports__["a"] = ({
47597  name: 'mousewheel',
47598  params: {
47599    mousewheel: {
47600      enabled: false,
47601      releaseOnEdges: false,
47602      invert: false,
47603      forceToAxis: false,
47604      sensitivity: 1,
47605      eventsTarget: 'container',
47606      thresholdDelta: null,
47607      thresholdTime: null
47608    }
47609  },
47610  create: function create() {
47611    var swiper = this;
47612    Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["a" /* bindModuleMethods */])(swiper, {
47613      mousewheel: {
47614        enabled: false,
47615        lastScrollTime: Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["i" /* now */])(),
47616        lastEventBeforeSnap: undefined,
47617        recentWheelEvents: [],
47618        enable: Mousewheel.enable,
47619        disable: Mousewheel.disable,
47620        handle: Mousewheel.handle,
47621        handleMouseEnter: Mousewheel.handleMouseEnter,
47622        handleMouseLeave: Mousewheel.handleMouseLeave,
47623        animateSlider: Mousewheel.animateSlider,
47624        releaseScroll: Mousewheel.releaseScroll
47625      }
47626    });
47627  },
47628  on: {
47629    init: function init(swiper) {
47630      if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) {
47631        swiper.mousewheel.disable();
47632      }
47633
47634      if (swiper.params.mousewheel.enabled) swiper.mousewheel.enable();
47635    },
47636    destroy: function destroy(swiper) {
47637      if (swiper.params.cssMode) {
47638        swiper.mousewheel.enable();
47639      }
47640
47641      if (swiper.mousewheel.enabled) swiper.mousewheel.disable();
47642    }
47643  }
47644});
47645
47646/***/ }),
47647/* 235 */
47648/***/ (function(module, __webpack_exports__, __webpack_require__) {
47649
47650"use strict";
47651/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_dom__ = __webpack_require__(3);
47652/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
47653function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
47654
47655
47656
47657var Navigation = {
47658  toggleEl: function toggleEl($el, disabled) {
47659    $el[disabled ? 'addClass' : 'removeClass'](this.params.navigation.disabledClass);
47660    if ($el[0] && $el[0].tagName === 'BUTTON') $el[0].disabled = disabled;
47661  },
47662  update: function update() {
47663    // Update Navigation Buttons
47664    var swiper = this;
47665    var params = swiper.params.navigation;
47666    var toggleEl = swiper.navigation.toggleEl;
47667    if (swiper.params.loop) return;
47668    var _swiper$navigation = swiper.navigation,
47669        $nextEl = _swiper$navigation.$nextEl,
47670        $prevEl = _swiper$navigation.$prevEl;
47671
47672    if ($prevEl && $prevEl.length > 0) {
47673      if (swiper.isBeginning) {
47674        toggleEl($prevEl, true);
47675      } else {
47676        toggleEl($prevEl, false);
47677      }
47678
47679      if (swiper.params.watchOverflow && swiper.enabled) {
47680        $prevEl[swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);
47681      }
47682    }
47683
47684    if ($nextEl && $nextEl.length > 0) {
47685      if (swiper.isEnd) {
47686        toggleEl($nextEl, true);
47687      } else {
47688        toggleEl($nextEl, false);
47689      }
47690
47691      if (swiper.params.watchOverflow && swiper.enabled) {
47692        $nextEl[swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);
47693      }
47694    }
47695  },
47696  onPrevClick: function onPrevClick(e) {
47697    var swiper = this;
47698    e.preventDefault();
47699    if (swiper.isBeginning && !swiper.params.loop) return;
47700    swiper.slidePrev();
47701  },
47702  onNextClick: function onNextClick(e) {
47703    var swiper = this;
47704    e.preventDefault();
47705    if (swiper.isEnd && !swiper.params.loop) return;
47706    swiper.slideNext();
47707  },
47708  init: function init() {
47709    var swiper = this;
47710    var params = swiper.params.navigation;
47711    swiper.params.navigation = Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["c" /* createElementIfNotDefined */])(swiper.$el, swiper.params.navigation, swiper.params.createElements, {
47712      nextEl: 'swiper-button-next',
47713      prevEl: 'swiper-button-prev'
47714    });
47715    if (!(params.nextEl || params.prevEl)) return;
47716    var $nextEl;
47717    var $prevEl;
47718
47719    if (params.nextEl) {
47720      $nextEl = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(params.nextEl);
47721
47722      if (swiper.params.uniqueNavElements && typeof params.nextEl === 'string' && $nextEl.length > 1 && swiper.$el.find(params.nextEl).length === 1) {
47723        $nextEl = swiper.$el.find(params.nextEl);
47724      }
47725    }
47726
47727    if (params.prevEl) {
47728      $prevEl = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(params.prevEl);
47729
47730      if (swiper.params.uniqueNavElements && typeof params.prevEl === 'string' && $prevEl.length > 1 && swiper.$el.find(params.prevEl).length === 1) {
47731        $prevEl = swiper.$el.find(params.prevEl);
47732      }
47733    }
47734
47735    if ($nextEl && $nextEl.length > 0) {
47736      $nextEl.on('click', swiper.navigation.onNextClick);
47737    }
47738
47739    if ($prevEl && $prevEl.length > 0) {
47740      $prevEl.on('click', swiper.navigation.onPrevClick);
47741    }
47742
47743    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["e" /* extend */])(swiper.navigation, {
47744      $nextEl: $nextEl,
47745      nextEl: $nextEl && $nextEl[0],
47746      $prevEl: $prevEl,
47747      prevEl: $prevEl && $prevEl[0]
47748    });
47749
47750    if (!swiper.enabled) {
47751      if ($nextEl) $nextEl.addClass(params.lockClass);
47752      if ($prevEl) $prevEl.addClass(params.lockClass);
47753    }
47754  },
47755  destroy: function destroy() {
47756    var swiper = this;
47757    var _swiper$navigation2 = swiper.navigation,
47758        $nextEl = _swiper$navigation2.$nextEl,
47759        $prevEl = _swiper$navigation2.$prevEl;
47760
47761    if ($nextEl && $nextEl.length) {
47762      $nextEl.off('click', swiper.navigation.onNextClick);
47763      $nextEl.removeClass(swiper.params.navigation.disabledClass);
47764    }
47765
47766    if ($prevEl && $prevEl.length) {
47767      $prevEl.off('click', swiper.navigation.onPrevClick);
47768      $prevEl.removeClass(swiper.params.navigation.disabledClass);
47769    }
47770  }
47771};
47772/* harmony default export */ __webpack_exports__["a"] = ({
47773  name: 'navigation',
47774  params: {
47775    navigation: {
47776      nextEl: null,
47777      prevEl: null,
47778      hideOnClick: false,
47779      disabledClass: 'swiper-button-disabled',
47780      hiddenClass: 'swiper-button-hidden',
47781      lockClass: 'swiper-button-lock'
47782    }
47783  },
47784  create: function create() {
47785    var swiper = this;
47786    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["a" /* bindModuleMethods */])(swiper, {
47787      navigation: _extends({}, Navigation)
47788    });
47789  },
47790  on: {
47791    init: function init(swiper) {
47792      swiper.navigation.init();
47793      swiper.navigation.update();
47794    },
47795    toEdge: function toEdge(swiper) {
47796      swiper.navigation.update();
47797    },
47798    fromEdge: function fromEdge(swiper) {
47799      swiper.navigation.update();
47800    },
47801    destroy: function destroy(swiper) {
47802      swiper.navigation.destroy();
47803    },
47804    'enable disable': function enableDisable(swiper) {
47805      var _swiper$navigation3 = swiper.navigation,
47806          $nextEl = _swiper$navigation3.$nextEl,
47807          $prevEl = _swiper$navigation3.$prevEl;
47808
47809      if ($nextEl) {
47810        $nextEl[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.navigation.lockClass);
47811      }
47812
47813      if ($prevEl) {
47814        $prevEl[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.navigation.lockClass);
47815      }
47816    },
47817    click: function click(swiper, e) {
47818      var _swiper$navigation4 = swiper.navigation,
47819          $nextEl = _swiper$navigation4.$nextEl,
47820          $prevEl = _swiper$navigation4.$prevEl;
47821      var targetEl = e.target;
47822
47823      if (swiper.params.navigation.hideOnClick && !Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(targetEl).is($prevEl) && !Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(targetEl).is($nextEl)) {
47824        if (swiper.pagination && swiper.params.pagination && swiper.params.pagination.clickable && (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))) return;
47825        var isHidden;
47826
47827        if ($nextEl) {
47828          isHidden = $nextEl.hasClass(swiper.params.navigation.hiddenClass);
47829        } else if ($prevEl) {
47830          isHidden = $prevEl.hasClass(swiper.params.navigation.hiddenClass);
47831        }
47832
47833        if (isHidden === true) {
47834          swiper.emit('navigationShow');
47835        } else {
47836          swiper.emit('navigationHide');
47837        }
47838
47839        if ($nextEl) {
47840          $nextEl.toggleClass(swiper.params.navigation.hiddenClass);
47841        }
47842
47843        if ($prevEl) {
47844          $prevEl.toggleClass(swiper.params.navigation.hiddenClass);
47845        }
47846      }
47847    }
47848  }
47849});
47850
47851/***/ }),
47852/* 236 */
47853/***/ (function(module, __webpack_exports__, __webpack_require__) {
47854
47855"use strict";
47856/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_dom__ = __webpack_require__(3);
47857/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
47858function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
47859
47860
47861
47862var Pagination = {
47863  update: function update() {
47864    // Render || Update Pagination bullets/items
47865    var swiper = this;
47866    var rtl = swiper.rtl;
47867    var params = swiper.params.pagination;
47868    if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return;
47869    var slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
47870    var $el = swiper.pagination.$el; // Current/Total
47871
47872    var current;
47873    var total = swiper.params.loop ? Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
47874
47875    if (swiper.params.loop) {
47876      current = Math.ceil((swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup);
47877
47878      if (current > slidesLength - 1 - swiper.loopedSlides * 2) {
47879        current -= slidesLength - swiper.loopedSlides * 2;
47880      }
47881
47882      if (current > total - 1) current -= total;
47883      if (current < 0 && swiper.params.paginationType !== 'bullets') current = total + current;
47884    } else if (typeof swiper.snapIndex !== 'undefined') {
47885      current = swiper.snapIndex;
47886    } else {
47887      current = swiper.activeIndex || 0;
47888    } // Types
47889
47890
47891    if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {
47892      var bullets = swiper.pagination.bullets;
47893      var firstIndex;
47894      var lastIndex;
47895      var midIndex;
47896
47897      if (params.dynamicBullets) {
47898        swiper.pagination.bulletSize = bullets.eq(0)[swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'](true);
47899        $el.css(swiper.isHorizontal() ? 'width' : 'height', swiper.pagination.bulletSize * (params.dynamicMainBullets + 4) + "px");
47900
47901        if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) {
47902          swiper.pagination.dynamicBulletIndex += current - swiper.previousIndex;
47903
47904          if (swiper.pagination.dynamicBulletIndex > params.dynamicMainBullets - 1) {
47905            swiper.pagination.dynamicBulletIndex = params.dynamicMainBullets - 1;
47906          } else if (swiper.pagination.dynamicBulletIndex < 0) {
47907            swiper.pagination.dynamicBulletIndex = 0;
47908          }
47909        }
47910
47911        firstIndex = current - swiper.pagination.dynamicBulletIndex;
47912        lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
47913        midIndex = (lastIndex + firstIndex) / 2;
47914      }
47915
47916      bullets.removeClass(params.bulletActiveClass + " " + params.bulletActiveClass + "-next " + params.bulletActiveClass + "-next-next " + params.bulletActiveClass + "-prev " + params.bulletActiveClass + "-prev-prev " + params.bulletActiveClass + "-main");
47917
47918      if ($el.length > 1) {
47919        bullets.each(function (bullet) {
47920          var $bullet = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(bullet);
47921          var bulletIndex = $bullet.index();
47922
47923          if (bulletIndex === current) {
47924            $bullet.addClass(params.bulletActiveClass);
47925          }
47926
47927          if (params.dynamicBullets) {
47928            if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
47929              $bullet.addClass(params.bulletActiveClass + "-main");
47930            }
47931
47932            if (bulletIndex === firstIndex) {
47933              $bullet.prev().addClass(params.bulletActiveClass + "-prev").prev().addClass(params.bulletActiveClass + "-prev-prev");
47934            }
47935
47936            if (bulletIndex === lastIndex) {
47937              $bullet.next().addClass(params.bulletActiveClass + "-next").next().addClass(params.bulletActiveClass + "-next-next");
47938            }
47939          }
47940        });
47941      } else {
47942        var $bullet = bullets.eq(current);
47943        var bulletIndex = $bullet.index();
47944        $bullet.addClass(params.bulletActiveClass);
47945
47946        if (params.dynamicBullets) {
47947          var $firstDisplayedBullet = bullets.eq(firstIndex);
47948          var $lastDisplayedBullet = bullets.eq(lastIndex);
47949
47950          for (var i = firstIndex; i <= lastIndex; i += 1) {
47951            bullets.eq(i).addClass(params.bulletActiveClass + "-main");
47952          }
47953
47954          if (swiper.params.loop) {
47955            if (bulletIndex >= bullets.length - params.dynamicMainBullets) {
47956              for (var _i = params.dynamicMainBullets; _i >= 0; _i -= 1) {
47957                bullets.eq(bullets.length - _i).addClass(params.bulletActiveClass + "-main");
47958              }
47959
47960              bullets.eq(bullets.length - params.dynamicMainBullets - 1).addClass(params.bulletActiveClass + "-prev");
47961            } else {
47962              $firstDisplayedBullet.prev().addClass(params.bulletActiveClass + "-prev").prev().addClass(params.bulletActiveClass + "-prev-prev");
47963              $lastDisplayedBullet.next().addClass(params.bulletActiveClass + "-next").next().addClass(params.bulletActiveClass + "-next-next");
47964            }
47965          } else {
47966            $firstDisplayedBullet.prev().addClass(params.bulletActiveClass + "-prev").prev().addClass(params.bulletActiveClass + "-prev-prev");
47967            $lastDisplayedBullet.next().addClass(params.bulletActiveClass + "-next").next().addClass(params.bulletActiveClass + "-next-next");
47968          }
47969        }
47970      }
47971
47972      if (params.dynamicBullets) {
47973        var dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
47974        var bulletsOffset = (swiper.pagination.bulletSize * dynamicBulletsLength - swiper.pagination.bulletSize) / 2 - midIndex * swiper.pagination.bulletSize;
47975        var offsetProp = rtl ? 'right' : 'left';
47976        bullets.css(swiper.isHorizontal() ? offsetProp : 'top', bulletsOffset + "px");
47977      }
47978    }
47979
47980    if (params.type === 'fraction') {
47981      $el.find(Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["b" /* classesToSelector */])(params.currentClass)).text(params.formatFractionCurrent(current + 1));
47982      $el.find(Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["b" /* classesToSelector */])(params.totalClass)).text(params.formatFractionTotal(total));
47983    }
47984
47985    if (params.type === 'progressbar') {
47986      var progressbarDirection;
47987
47988      if (params.progressbarOpposite) {
47989        progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
47990      } else {
47991        progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
47992      }
47993
47994      var scale = (current + 1) / total;
47995      var scaleX = 1;
47996      var scaleY = 1;
47997
47998      if (progressbarDirection === 'horizontal') {
47999        scaleX = scale;
48000      } else {
48001        scaleY = scale;
48002      }
48003
48004      $el.find(Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["b" /* classesToSelector */])(params.progressbarFillClass)).transform("translate3d(0,
480040,0) scaleX(" + scaleX + ") scaleY(" + scaleY + ")").transition(swiper.params.speed);
48005    }
48006
48007    if (params.type === 'custom' && params.renderCustom) {
48008      $el.html(params.renderCustom(swiper, current + 1, total));
48009      swiper.emit('paginationRender', $el[0]);
48010    } else {
48011      swiper.emit('paginationUpdate', $el[0]);
48012    }
48013
48014    if (swiper.params.watchOverflow && swiper.enabled) {
48015      $el[swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);
48016    }
48017  },
48018  render: function render() {
48019    // Render Container
48020    var swiper = this;
48021    var params = swiper.params.pagination;
48022    if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return;
48023    var slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
48024    var $el = swiper.pagination.$el;
48025    var paginationHTML = '';
48026
48027    if (params.type === 'bullets') {
48028      var numberOfBullets = swiper.params.loop ? Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
48029
48030      if (swiper.params.freeMode && !swiper.params.loop && numberOfBullets > slidesLength) {
48031        numberOfBullets = slidesLength;
48032      }
48033
48034      for (var i = 0; i < numberOfBullets; i += 1) {
48035        if (params.renderBullet) {
48036          paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
48037        } else {
48038          paginationHTML += "<" + params.bulletElement + " class=\"" + params.bulletClass + "\"></" + params.bulletElement + ">";
48039        }
48040      }
48041
48042      $el.html(paginationHTML);
48043      swiper.pagination.bullets = $el.find(Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["b" /* classesToSelector */])(params.bulletClass));
48044    }
48045
48046    if (params.type === 'fraction') {
48047      if (params.renderFraction) {
48048        paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
48049      } else {
48050        paginationHTML = "<span class=\"" + params.currentClass + "\"></span>" + ' / ' + ("<span class=\"" + params.totalClass + "\"></span>");
48051      }
48052
48053      $el.html(paginationHTML);
48054    }
48055
48056    if (params.type === 'progressbar') {
48057      if (params.renderProgressbar) {
48058        paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
48059      } else {
48060        paginationHTML = "<span class=\"" + params.progressbarFillClass + "\"></span>";
48061      }
48062
48063      $el.html(paginationHTML);
48064    }
48065
48066    if (params.type !== 'custom') {
48067      swiper.emit('paginationRender', swiper.pagination.$el[0]);
48068    }
48069  },
48070  init: function init() {
48071    var swiper = this;
48072    swiper.params.pagination = Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["c" /* createElementIfNotDefined */])(swiper.$el, swiper.params.pagination, swiper.params.createElements, {
48073      el: 'swiper-pagination'
48074    });
48075    var params = swiper.params.pagination;
48076    if (!params.el) return;
48077    var $el = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(params.el);
48078    if ($el.length === 0) return;
48079
48080    if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1) {
48081      $el = swiper.$el.find(params.el);
48082    }
48083
48084    if (params.type === 'bullets' && params.clickable) {
48085      $el.addClass(params.clickableClass);
48086    }
48087
48088    $el.addClass(params.modifierClass + params.type);
48089
48090    if (params.type === 'bullets' && params.dynamicBullets) {
48091      $el.addClass("" + params.modifierClass + params.type + "-dynamic");
48092      swiper.pagination.dynamicBulletIndex = 0;
48093
48094      if (params.dynamicMainBullets < 1) {
48095        params.dynamicMainBullets = 1;
48096      }
48097    }
48098
48099    if (params.type === 'progressbar' && params.progressbarOpposite) {
48100      $el.addClass(params.progressbarOppositeClass);
48101    }
48102
48103    if (params.clickable) {
48104      $el.on('click', Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["b" /* classesToSelector */])(params.bulletClass), function onClick(e) {
48105        e.preventDefault();
48106        var index = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(this).index() * swiper.params.slidesPerGroup;
48107        if (swiper.params.loop) index += swiper.loopedSlides;
48108        swiper.slideTo(index);
48109      });
48110    }
48111
48112    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["e" /* extend */])(swiper.pagination, {
48113      $el: $el,
48114      el: $el[0]
48115    });
48116
48117    if (!swiper.enabled) {
48118      $el.addClass(params.lockClass);
48119    }
48120  },
48121  destroy: function destroy() {
48122    var swiper = this;
48123    var params = swiper.params.pagination;
48124    if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return;
48125    var $el = swiper.pagination.$el;
48126    $el.removeClass(params.hiddenClass);
48127    $el.removeClass(params.modifierClass + params.type);
48128    if (swiper.pagination.bullets) swiper.pagination.bullets.removeClass(params.bulletActiveClass);
48129
48130    if (params.clickable) {
48131      $el.off('click', Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["b" /* classesToSelector */])(params.bulletClass));
48132    }
48133  }
48134};
48135/* harmony default export */ __webpack_exports__["a"] = ({
48136  name: 'pagination',
48137  params: {
48138    pagination: {
48139      el: null,
48140      bulletElement: 'span',
48141      clickable: false,
48142      hideOnClick: false,
48143      renderBullet: null,
48144      renderProgressbar: null,
48145      renderFraction: null,
48146      renderCustom: null,
48147      progressbarOpposite: false,
48148      type: 'bullets',
48149      // 'bullets' or 'progressbar' or 'fraction' or 'custom'
48150      dynamicBullets: false,
48151      dynamicMainBullets: 1,
48152      formatFractionCurrent: function formatFractionCurrent(number) {
48153        return number;
48154      },
48155      formatFractionTotal: function formatFractionTotal(number) {
48156        return number;
48157      },
48158      bulletClass: 'swiper-pagination-bullet',
48159      bulletActiveClass: 'swiper-pagination-bullet-active',
48160      modifierClass: 'swiper-pagination-',
48161      // NEW
48162      currentClass: 'swiper-pagination-current',
48163      totalClass: 'swiper-pagination-total',
48164      hiddenClass: 'swiper-pagination-hidden',
48165      progressbarFillClass: 'swiper-pagination-progressbar-fill',
48166      progressbarOppositeClass: 'swiper-pagination-progressbar-opposite',
48167      clickableClass: 'swiper-pagination-clickable',
48168      // NEW
48169      lockClass: 'swiper-pagination-lock'
48170    }
48171  },
48172  create: function create() {
48173    var swiper = this;
48174    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["a" /* bindModuleMethods */])(swiper, {
48175      pagination: _extends({
48176        dynamicBulletIndex: 0
48177      }, Pagination)
48178    });
48179  },
48180  on: {
48181    init: function init(swiper) {
48182      swiper.pagination.init();
48183      swiper.pagination.render();
48184      swiper.pagination.update();
48185    },
48186    activeIndexChange: function activeIndexChange(swiper) {
48187      if (swiper.params.loop) {
48188        swiper.pagination.update();
48189      } else if (typeof swiper.snapIndex === 'undefined') {
48190        swiper.pagination.update();
48191      }
48192    },
48193    snapIndexChange: function snapIndexChange(swiper) {
48194      if (!swiper.params.loop) {
48195        swiper.pagination.update();
48196      }
48197    },
48198    slidesLengthChange: function slidesLengthChange(swiper) {
48199      if (swiper.params.loop) {
48200        swiper.pagination.render();
48201        swiper.pagination.update();
48202      }
48203    },
48204    snapGridLengthChange: function snapGridLengthChange(swiper) {
48205      if (!swiper.params.loop) {
48206        swiper.pagination.render();
48207        swiper.pagination.update();
48208      }
48209    },
48210    destroy: function destroy(swiper) {
48211      swiper.pagination.destroy();
48212    },
48213    'enable disable': function enableDisable(swiper) {
48214      var $el = swiper.pagination.$el;
48215
48216      if ($el) {
48217        $el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.pagination.lockClass);
48218      }
48219    },
48220    click: function click(swiper, e) {
48221      var targetEl = e.target;
48222
48223      if (swiper.params.pagination.el && swiper.params.pagination.hideOnClick && swiper.pagination.$el.length > 0 && !Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(targetEl).hasClass(swiper.params.pagination.bulletClass)) {
48224        if (swiper.navigation && (swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl || swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl)) return;
48225        var isHidden = swiper.pagination.$el.hasClass(swiper.params.pagination.hiddenClass);
48226
48227        if (isHidden === true) {
48228          swiper.emit('paginationShow');
48229        } else {
48230          swiper.emit('paginationHide');
48231        }
48232
48233        swiper.pagination.$el.toggleClass(swiper.params.pagination.hiddenClass);
48234      }
48235    }
48236  }
48237});
48238
48239/***/ }),
48240/* 237 */
48241/***/ (function(module, __webpack_exports__, __webpack_require__) {
48242
48243"use strict";
48244/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
48245/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_dom__ = __webpack_require__(3);
48246/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_utils__ = __webpack_require__(1);
48247function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
48248
48249
48250
48251
48252var Scrollbar = {
48253  setTranslate: function setTranslate() {
48254    var swiper = this;
48255    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
48256    var scrollbar = swiper.scrollbar,
48257        rtl = swiper.rtlTranslate,
48258        progress = swiper.progress;
48259    var dragSize = scrollbar.dragSize,
48260        trackSize = scrollbar.trackSize,
48261        $dragEl = scrollbar.$dragEl,
48262        $el = scrollbar.$el;
48263    var params = swiper.params.scrollbar;
48264    var newSize = dragSize;
48265    var newPos = (trackSize - dragSize) * progress;
48266
48267    if (rtl) {
48268      newPos = -newPos;
48269
48270      if (newPos > 0) {
48271        newSize = dragSize - newPos;
48272        newPos = 0;
48273      } else if (-newPos + dragSize > trackSize) {
48274        newSize = trackSize + newPos;
48275      }
48276    } else if (newPos < 0) {
48277      newSize = dragSize + newPos;
48278      newPos = 0;
48279    } else if (newPos + dragSize > trackSize) {
48280      newSize = trackSize - newPos;
48281    }
48282
48283    if (swiper.isHorizontal()) {
48284      $dragEl.transform("translate3d(" + newPos + "px, 0, 0)");
48285      $dragEl[0].style.width = newSize + "px";
48286    } else {
48287      $dragEl.transform("translate3d(0px, " + newPos + "px, 0)");
48288      $dragEl[0].style.height = newSize + "px";
48289    }
48290
48291    if (params.hide) {
48292      clearTimeout(swiper.scrollbar.timeout);
48293      $el[0].style.opacity = 1;
48294      swiper.scrollbar.timeout = setTimeout(function () {
48295        $el[0].style.opacity = 0;
48296        $el.transition(400);
48297      }, 1000);
48298    }
48299  },
48300  setTransition: function setTransition(duration) {
48301    var swiper = this;
48302    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
48303    swiper.scrollbar.$dragEl.transition(duration);
48304  },
48305  updateSize: function updateSize() {
48306    var swiper = this;
48307    if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
48308    var scrollbar = swiper.scrollbar;
48309    var $dragEl = scrollbar.$dragEl,
48310        $el = scrollbar.$el;
48311    $dragEl[0].style.width = '';
48312    $dragEl[0].style.height = '';
48313    var trackSize = swiper.isHorizontal() ? $el[0].offsetWidth : $el[0].offsetHeight;
48314    var divider = swiper.size / swiper.virtualSize;
48315    var moveDivider = divider * (trackSize / swiper.size);
48316    var dragSize;
48317
48318    if (swiper.params.scrollbar.dragSize === 'auto') {
48319      dragSize = trackSize * divider;
48320    } else {
48321      dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);
48322    }
48323
48324    if (swiper.isHorizontal()) {
48325      $dragEl[0].style.width = dragSize + "px";
48326    } else {
48327      $dragEl[0].style.height = dragSize + "px";
48328    }
48329
48330    if (divider >= 1) {
48331      $el[0].style.display = 'none';
48332    } else {
48333      $el[0].style.display = '';
48334    }
48335
48336    if (swiper.params.scrollbar.hide) {
48337      $el[0].style.opacity = 0;
48338    }
48339
48340    Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])(scrollbar, {
48341      trackSize: trackSize,
48342      divider: divider,
48343      moveDivider: moveDivider,
48344      dragSize: dragSize
48345    });
48346
48347    if (swiper.params.watchOverflow && swiper.enabled) {
48348      scrollbar.$el[swiper.isLocked ? 'addClass' : 'removeClass'](swiper.params.scrollbar.lockClass);
48349    }
48350  },
48351  getPointerPosition: function getPointerPosition(e) {
48352    var swiper = this;
48353
48354    if (swiper.isHorizontal()) {
48355      return e.type === 'touchstart' || e.type === 'touchmove' ? e.targetTouches[0].clientX : e.clientX;
48356    }
48357
48358    return e.type === 'touchstart' || e.type === 'touchmove' ? e.targetTouches[0].clientY : e.clientY;
48359  },
48360  setDragPosition: function setDragPosition(e) {
48361    var swiper = this;
48362    var scrollbar = swiper.scrollbar,
48363        rtl = swiper.rtlTranslate;
48364    var $el = scrollbar.$el,
48365        dragSize = scrollbar.dragSize,
48366        trackSize = scrollbar.trackSize,
48367        dragStartPos = scrollbar.dragStartPos;
48368    var positionRatio;
48369    positionRatio = (scrollbar.getPointerPosition(e) - $el.offset()[swiper.isHorizontal() ? 'left' : 'top'] - (dragStartPos !== null ? dragStartPos : dragSize / 2)) / (trackSize - dragSize);
48370    positionRatio = Math.max(Math.min(positionRatio, 1), 0);
48371
48372    if (rtl) {
48373      positionRatio = 1 - positionRatio;
48374    }
48375
48376    var position = swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;
48377    swiper.updateProgress(position);
48378    swiper.setTranslate(position);
48379    swiper.updateActiveIndex();
48380    swiper.updateSlidesClasses();
48381  },
48382  onDragStart: function onDragStart(e) {
48383    var swiper = this;
48384    var params = swiper.params.scrollbar;
48385    var scrollbar = swiper.scrollbar,
48386        $wrapperEl = swiper.$wrapperEl;
48387    var $el = scrollbar.$el,
48388        $dragEl = scrollbar.$dragEl;
48389    swiper.scrollbar.isTouched = true;
48390    swiper.scrollbar.dragStartPos = e.target === $dragEl[0] || e.target === $dragEl ? scrollbar.getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] : null;
48391    e.preventDefault();
48392    e.stopPropagation();
48393    $wrapperEl.transition(100);
48394    $dragEl.transition(100);
48395    scrollbar.setDragPosition(e);
48396    clearTimeout(swiper.scrollbar.dragTimeout);
48397    $el.transition(0);
48398
48399    if (params.hide) {
48400      $el.css('opacity', 1);
48401    }
48402
48403    if (swiper.params.cssMode) {
48404      swiper.$wrapperEl.css('scroll-snap-type', 'none');
48405    }
48406
48407    swiper.emit('scrollbarDragStart', e);
48408  },
48409  onDragMove: function onDragMove(e) {
48410    var swiper = this;
48411    var scrollbar = swiper.scrollbar,
48412        $wrapperEl = swiper.$wrapperEl;
48413    var $el = scrollbar.$el,
48414        $dragEl = scrollbar.$dragEl;
48415    if (!swiper.scrollbar.isTouched) return;
48416    if (e.preventDefault) e.preventDefault();else e.returnValue = false;
48417    scrollbar.setDragPosition(e);
48418    $wrapperEl.transition(0);
48419    $el.transition(0);
48420    $dragEl.transition(0);
48421    swiper.emit('scrollbarDragMove', e);
48422  },
48423  onDragEnd: function onDragEnd(e) {
48424    var swiper = this;
48425    var params = swiper.params.scrollbar;
48426    var scrollbar = swiper.scrollbar,
48427        $wrapperEl = swiper.$wrapperEl;
48428    var $el = scrollbar.$el;
48429    if (!swiper.scrollbar.isTouched) return;
48430    swiper.scrollbar.isTouched = false;
48431
48432    if (swiper.params.cssMode) {
48433      swiper.$wrapperEl.css('scroll-snap-type', '');
48434      $wrapperEl.transition('');
48435    }
48436
48437    if (params.hide) {
48438      clearTimeout(swiper.scrollbar.dragTimeout);
48439      swiper.scrollbar.dragTimeout = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["h" /* nextTick */])(function () {
48440        $el.css('opacity', 0);
48441        $el.transition(400);
48442      }, 1000);
48443    }
48444
48445    swiper.emit('scrollbarDragEnd', e);
48446
48447    if (params.snapOnRelease) {
48448      swiper.slideToClosest();
48449    }
48450  },
48451  enableDraggable: function enableDraggable() {
48452    var swiper = this;
48453    if (!swiper.params.scrollbar.el) return;
48454    var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
48455    var scrollbar = swiper.scrollbar,
48456        touchEventsTouch = swiper.touchEventsTouch,
48457        touchEventsDesktop = swiper.touchEventsDesktop,
48458        params = swiper.params,
48459        support = swiper.support;
48460    var $el = scrollbar.$el;
48461    var target = $el[0];
48462    var activeListener = support.passiveListener && params.passiveListeners ? {
48463      passive: false,
48464      capture: false
48465    } : false;
48466    var passiveListener = support.passiveListener && params.passiveListeners ? {
48467      passive: true,
48468      capture: false
48469    } : false;
48470    if (!target) return;
48471
48472    if (!support.touch) {
48473      target.addEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener);
48474      document.addEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener);
48475      document.addEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener);
48476    } else {
48477      target.addEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener);
48478      target.addEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener);
48479      target.addEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener);
48480    }
48481  },
48482  disableDraggable: function disableDraggable() {
48483    var swiper = this;
48484    if (!swiper.params.scrollbar.el) return;
48485    var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
48486    var scrollbar = swiper.scrollbar,
48487        touchEventsTouch = swiper.touchEventsTouch,
48488        touchEventsDesktop = swiper.touchEventsDesktop,
48489        params = swiper.params,
48490        support = swiper.support;
48491    var $el = scrollbar.$el;
48492    var target = $el[0];
48493    var activeListener = support.passiveListener && params.passiveListeners ? {
48494      passive: false,
48495      capture: false
48496    } : false;
48497    var passiveListener = support.passiveListener && params.passiveListeners ? {
48498      passive: true,
48499      capture: false
48500    } : false;
48501    if (!target) return;
48502
48503    if (!support.touch) {
48504      target.removeEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener);
48505      document.removeEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener);
48506      document.removeEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener);
48507    } else {
48508      target.removeEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener);
48509      target.removeEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener);
48510      target.removeEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener);
48511    }
48512  },
48513  init: function init() {
48514    var swiper = this;
48515    var scrollbar = swiper.scrollbar,
48516        $swiperEl = swiper.$el;
48517    swiper.params.scrollbar = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["c" /* createElementIfNotDefined */])($swiperEl, swiper.params.scrollbar, swiper.params.createElements, {
48518      el: 'swiper-scrollbar'
48519    });
48520    var params = swiper.params.scrollbar;
48521    if (!params.el) return;
48522    var $el = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(params.el);
48523
48524    if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1 && $swiperEl.find(params.el).length === 1) {
48525      $el = $swiperEl.find(params.el);
48526    }
48527
48528    var $dragEl = $el.find("." + swiper.params.scrollbar.dragClass);
48529
48530    if ($dragEl.length === 0) {
48531      $dragEl = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])("<div class=\"" + swiper.params.scrollbar.dragClass + "\"></div>");
48532      $el.append($dragEl);
48533    }
48534
48535    Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["e" /* extend */])(scrollbar, {
48536      $el: $el,
48537      el: $el[0],
48538      $dragEl: $dragEl,
48539      dragEl: $dragEl[0]
48540    });
48541
48542    if (params.draggable) {
48543      scrollbar.enableDraggable();
48544    }
48545
48546    if ($el) {
48547      $el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.scrollbar.lockClass);
48548    }
48549  },
48550  destroy: function destroy() {
48551    var swiper = this;
48552    swiper.scrollbar.disableDraggable();
48553  }
48554};
48555/* harmony default export */ __webpack_exports__["a"] = ({
48556  name: 'scrollbar',
48557  params: {
48558    scrollbar: {
48559      el: null,
48560      dragSize: 'auto',
48561      hide: false,
48562      draggable: false,
48563      snapOnRelease: true,
48564      lockClass: 'swiper-scrollbar-lock',
48565      dragClass: 'swiper-scrollbar-drag'
48566    }
48567  },
48568  create: function create() {
48569    var swiper = this;
48570    Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["a" /* bindModuleMethods */])(swiper, {
48571      scrollbar: _extends({
48572        isTouched: false,
48573        timeout: null,
48574        dragTimeout: null
48575      }, Scrollbar)
48576    });
48577  },
48578  on: {
48579    init: function init(swiper) {
48580      swiper.scrollbar.init();
48581      swiper.scrollbar.updateSize();
48582      swiper.scrollbar.setTranslate();
48583    },
48584    update: function update(swiper) {
48585      swiper.scrollbar.updateSize();
48586    },
48587    resize: function resize(swiper) {
48588      swiper.scrollbar.updateSize();
48589    },
48590    observerUpdate: function observerUpdate(swiper) {
48591      swiper.scrollbar.updateSize();
48592    },
48593    setTranslate: function setTranslate(swiper) {
48594      swiper.scrollbar.setTranslate();
48595    },
48596    setTransition: function setTransition(swiper, duration) {
48597      swiper.scrollbar.setTransition(duration);
48598    },
48599    'enable disable': function enableDisable(swiper) {
48600      var $el = swiper.scrollbar.$el;
48601
48602      if ($el) {
48603        $el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.scrollbar.lockClass);
48604      }
48605    },
48606    destroy: function destroy(swiper) {
48607      swiper.scrollbar.destroy();
48608    }
48609  }
48610});
48611
48612/***/ }),
48613/* 238 */
48614/***/ (function(module, __webpack_exports__, __webpack_require__) {
48615
48616"use strict";
48617/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_dom__ = __webpack_require__(3);
48618/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
48619function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
48620
48621
48622
48623var Parallax = {
48624  setTransform: function setTransform(el, progress) {
48625    var swiper = this;
48626    var rtl = swiper.rtl;
48627    var $el = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(el);
48628    var rtlFactor = rtl ? -1 : 1;
48629    var p = $el.attr('data-swiper-parallax') || '0';
48630    var x = $el.attr('data-swiper-parallax-x');
48631    var y = $el.attr('data-swiper-parallax-y');
48632    var scale = $el.attr('data-swiper-parallax-scale');
48633    var opacity = $el.attr('data-swiper-parallax-opacity');
48634
48635    if (x || y) {
48636      x = x || '0';
48637      y = y || '0';
48638    } else if (swiper.isHorizontal()) {
48639      x = p;
48640      y = '0';
48641    } else {
48642      y = p;
48643      x = '0';
48644    }
48645
48646    if (x.indexOf('%') >= 0) {
48647      x = parseInt(x, 10) * progress * rtlFactor + "%";
48648    } else {
48649      x = x * progress * rtlFactor + "px";
48650    }
48651
48652    if (y.indexOf('%') >= 0) {
48653      y = parseInt(y, 10) * progress + "%";
48654    } else {
48655      y = y * progress + "px";
48656    }
48657
48658    if (typeof opacity !== 'undefined' && opacity !== null) {
48659      var currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress));
48660      $el[0].style.opacity = currentOpacity;
48661    }
48662
48663    if (typeof scale === 'undefined' || scale === null) {
48664      $el.transform("translate3d(" + x + ", " + y + ", 0px)");
48665    } else {
48666      var currentScale = scale - (scale - 1) * (1 - Math.abs(progress));
48667      $el.transform("translate3d(" + x + ", " + y + ", 0px) scale(" + currentScale + ")");
48668    }
48669  },
48670  setTranslate: function setTranslate() {
48671    var swiper = this;
48672    var $el = swiper.$el,
48673        slides = swiper.slides,
48674        progress = swiper.progress,
48675        snapGrid = swiper.snapGrid;
48676    $el.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(function (el) {
48677      swiper.parallax.setTransform(el, progress);
48678    });
48679    slides.each(function (slideEl, slideIndex) {
48680      var slideProgress = slideEl.progress;
48681
48682      if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {
48683        slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1);
48684      }
48685
48686      slideProgress = Math.min(Math.max(slideProgress, -1), 1);
48687      Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(slideEl).find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(function (el) {
48688        swiper.parallax.setTransform(el, slideProgress);
48689      });
48690    });
48691  },
48692  setTransition: function setTransition(duration) {
48693    if (duration === void 0) {
48694      duration = this.params.speed;
48695    }
48696
48697    var swiper = this;
48698    var $el = swiper.$el;
48699    $el.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]').each(function (parallaxEl) {
48700      var $parallaxEl = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(parallaxEl);
48701      var parallaxDuration = parseInt($parallaxEl.attr('data-swiper-parallax-duration'), 10) || duration;
48702      if (duration === 0) parallaxDuration = 0;
48703      $parallaxEl.transition(parallaxDuration);
48704    });
48705  }
48706};
48707/* harmony default export */ __webpack_exports__["a"] = ({
48708  name: 'parallax',
48709  params: {
48710    parallax: {
48711      enabled: false
48712    }
48713  },
48714  create: function create() {
48715    var swiper = this;
48716    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["a" /* bindModuleMethods */])(swiper, {
48717      parallax: _extends({}, Parallax)
48718    });
48719  },
48720  on: {
48721    beforeInit: function beforeInit(swiper) {
48722      if (!swiper.params.parallax.enabled) return;
48723      swiper.params.watchSlidesProgress = true;
48724      swiper.originalParams.watchSlidesProgress = true;
48725    },
48726    init: function init(swiper) {
48727      if (!swiper.params.parallax.enabled) return;
48728      swiper.parallax.setTranslate();
48729    },
48730    setTranslate: function setTranslate(swiper) {
48731      if (!swiper.params.parallax.enabled) return;
48732      swiper.parallax.setTranslate();
48733    },
48734    setTransition: function setTransition(swiper, duration) {
48735      if (!swiper.params.parallax.enabled) return;
48736      swiper.parallax.setTransition(duration);
48737    }
48738  }
48739});
48740
48741/***/ }),
48742/* 239 */
48743/***/ (function(module, __webpack_exports__, __webpack_require__) {
48744
48745"use strict";
48746/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
48747/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_dom__ = __webpack_require__(3);
48748/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_utils__ = __webpack_require__(1);
48749function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
48750
48751
48752
48753
48754var Zoom = {
48755  // Calc Scale From Multi-touches
48756  getDistanceBetweenTouches: function getDistanceBetweenTouches(e) {
48757    if (e.targetTouches.length < 2) return 1;
48758    var x1 = e.targetTouches[0].pageX;
48759    var y1 = e.targetTouches[0].pageY;
48760    var x2 = e.targetTouches[1].pageX;
48761    var y2 = e.targetTouches[1].pageY;
48762    var distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
48763    return distance;
48764  },
48765  // Events
48766  onGestureStart: function onGestureStart(e) {
48767    var swiper = this;
48768    var support = swiper.support;
48769    var params = swiper.params.zoom;
48770    var zoom = swiper.zoom;
48771    var gesture = zoom.gesture;
48772    zoom.fakeGestureTouched = false;
48773    zoom.fakeGestureMoved = false;
48774
48775    if (!support.gestures) {
48776      if (e.type !== 'touchstart' || e.type === 'touchstart' && e.targetTouches.length < 2) {
48777        return;
48778      }
48779
48780      zoom.fakeGestureTouched = true;
48781      gesture.scaleStart = Zoom.getDistanceBetweenTouches(e);
48782    }
48783
48784    if (!gesture.$slideEl || !gesture.$slideEl.length) {
48785      gesture.$slideEl = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(e.target).closest("." + swiper.params.slideClass);
48786      if (gesture.$slideEl.length === 0) gesture.$slideEl = swiper.slides.eq(swiper.activeIndex);
48787      gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas, picture, .swiper-zoom-target');
48788      gesture.$imageWrapEl = gesture.$imageEl.parent("." + params.containerClass);
48789      gesture.maxRatio = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;
48790
48791      if (gesture.$imageWrapEl.length === 0) {
48792        gesture.$imageEl = undefined;
48793        return;
48794      }
48795    }
48796
48797    if (gesture.$imageEl) {
48798      gesture.$imageEl.transition(0);
48799    }
48800
48801    swiper.zoom.isScaling = true;
48802  },
48803  onGestureChange: function onGestureChange(e) {
48804    var swiper = this;
48805    var support = swiper.support;
48806    var params = swiper.params.zoom;
48807    var zoom = swiper.zoom;
48808    var gesture = zoom.gesture;
48809
48810    if (!support.gestures) {
48811      if (e.type !== 'touchmove' || e.type === 'touchmove' && e.targetTouches.length < 2) {
48812        return;
48813      }
48814
48815      zoom.fakeGestureMoved = true;
48816      gesture.scaleMove = Zoom.getDistanceBetweenTouches(e);
48817    }
48818
48819    if (!gesture.$imageEl || gesture.$imageEl.length === 0) {
48820      if (e.type === 'gesturechange') zoom.onGestureStart(e);
48821      return;
48822    }
48823
48824    if (support.gestures) {
48825      zoom.scale = e.scale * zoom.currentScale;
48826    } else {
48827      zoom.scale = gesture.scaleMove / gesture.scaleStart * zoom.currentScale;
48828    }
48829
48830    if (zoom.scale > gesture.maxRatio) {
48831      zoom.scale = gesture.maxRatio - 1 + Math.pow(zoom.scale - gesture.maxRatio + 1, 0.5);
48832    }
48833
48834    if (zoom.scale < params.minRatio) {
48835      zoom.scale = params.minRatio + 1 - Math.pow(params.minRatio - zoom.scale + 1, 0.5);
48836    }
48837
48838    gesture.$imageEl.transform("translate3d(0,0,0) scale(" + zoom.scale + ")");
48839  },
48840  onGestureEnd: function onGestureEnd(e) {
48841    var swiper = this;
48842    var device = swiper.device;
48843    var support = swiper.support;
48844    var params = swiper.params.zoom;
48845    var zoom = swiper.zoom;
48846    var gesture = zoom.gesture;
48847
48848    if (!support.gestures) {
48849      if (!zoom.fakeGestureTouched || !zoom.fakeGestureMoved) {
48850        return;
48851      }
48852
48853      if (e.type !== 'touchend' || e.type === 'touchend' && e.changedTouches.length < 2 && !device.android) {
48854        return;
48855      }
48856
48857      zoom.fakeGestureTouched = false;
48858      zoom.fakeGestureMoved = false;
48859    }
48860
48861    if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;
48862    zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio);
48863    gesture.$imageEl.transition(swiper.params.speed).transform("translate3d(0,0,0) scale(" + zoom.scale + ")");
48864    zoom.currentScale = zoom.scale;
48865    zoom.isScaling = false;
48866    if (zoom.scale === 1) gesture.$slideEl = undefined;
48867  },
48868  onTouchStart: function onTouchStart(e) {
48869    var swiper = this;
48870    var device = swiper.device;
48871    var zoom = swiper.zoom;
48872    var gesture = zoom.gesture,
48873        image = zoom.image;
48874    if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;
48875    if (image.isTouched) return;
48876    if (device.android && e.cancelable) e.preventDefault();
48877    image.isTouched = true;
48878    image.touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
48879    image.touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
48880  },
48881  onTouchMove: function onTouchMove(e) {
48882    var swiper = this;
48883    var zoom = swiper.zoom;
48884    var gesture = zoom.gesture,
48885        image = zoom.image,
48886        velocity = zoom.velocity;
48887    if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;
48888    swiper.allowClick = false;
48889    if (!image.isTouched || !gesture.$slideEl) return;
48890
48891    if (!image.isMoved) {
48892      image.width = gesture.$imageEl[0].offsetWidth;
48893      image.height = gesture.$imageEl[0].offsetHeight;
48894      image.startX = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["f" /* getTranslate */])(gesture.$imageWrapEl[0], 'x') || 0;
48895      image.startY = Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["f" /* getTranslate */])(gesture.$imageWrapEl[0], 'y') || 0;
48896      gesture.slideWidth = gesture.$slideEl[0].offsetWidth;
48897      gesture.slideHeight = gesture.$slideEl[0].offsetHeight;
48898      gesture.$imageWrapEl.transition(0);
48899    } // Define if we need image drag
48900
48901
48902    var scaledWidth = image.width * zoom.scale;
48903    var scaledHeight = image.height * zoom.scale;
48904    if (scaledWidth < gesture.slideWidth && scaledHeight < gesture.slideHeight) return;
48905    image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
48906    image.maxX = -image.minX;
48907    image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
48908    image.maxY = -image.minY;
48909    image.touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
48910    image.touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
48911
48912    if (!image.isMoved && !zoom.isScaling) {
48913      if (swiper.isHorizontal() && (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x || Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x)) {
48914        image.isTouched = false;
48915        return;
48916      }
48917
48918      if (!swiper.isHorizontal() && (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y || Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y)) {
48919        image.isTouched = false;
48920        return;
48921      }
48922    }
48923
48924    if (e.cancelable) {
48925      e.preventDefault();
48926    }
48927
48928    e.stopPropagation();
48929    image.isMoved = true;
48930    image.currentX = image.touchesCurrent.x - image.touchesStart.x + image.startX;
48931    image.currentY = image.touchesCurrent.y - image.touchesStart.y + image.startY;
48932
48933    if (image.currentX < image.minX) {
48934      image.currentX = image.minX + 1 - Math.pow(image.minX - image.currentX + 1, 0.8);
48935    }
48936
48937    if (image.currentX > image.maxX) {
48938      image.currentX = image.maxX - 1 + Math.pow(image.currentX - image.maxX + 1, 0.8);
48939    }
48940
48941    if (image.currentY < image.minY) {
48942      image.currentY = image.minY + 1 - Math.pow(image.minY - image.currentY + 1, 0.8);
48943    }
48944
48945    if (image.currentY > image.maxY) {
48946      image.currentY = image.maxY - 1 + Math.pow(image.currentY - image.maxY + 1, 0.8);
48947    } // Velocity
48948
48949
48950    if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x;
48951    if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y;
48952    if (!velocity.prevTime) velocity.prevTime = Date.now();
48953    velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2;
48954    velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2;
48955    if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0;
48956    if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0;
48957    velocity.prevPositionX = image.touchesCurrent.x;
48958    velocity.prevPositionY = image.touchesCurrent.y;
48959    velocity.prevTime = Date.now();
48960    gesture.$imageWrapEl.transform("translate3d(" + image.currentX + "px, " + image.currentY + "px,0
48960)");
48961  },
48962  onTouchEnd: function onTouchEnd() {
48963    var swiper = this;
48964    var zoom = swiper.zoom;
48965    var gesture = zoom.gesture,
48966        image = zoom.image,
48967        velocity = zoom.velocity;
48968    if (!gesture.$imageEl || gesture.$imageEl.length === 0) return;
48969
48970    if (!image.isTouched || !image.isMoved) {
48971      image.isTouched = false;
48972      image.isMoved = false;
48973      return;
48974    }
48975
48976    image.isTouched = false;
48977    image.isMoved = false;
48978    var momentumDurationX = 300;
48979    var momentumDurationY = 300;
48980    var momentumDistanceX = velocity.x * momentumDurationX;
48981    var newPositionX = image.currentX + momentumDistanceX;
48982    var momentumDistanceY = velocity.y * momentumDurationY;
48983    var newPositionY = image.currentY + momentumDistanceY; // Fix duration
48984
48985    if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x);
48986    if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y);
48987    var momentumDuration = Math.max(momentumDurationX, momentumDurationY);
48988    image.currentX = newPositionX;
48989    image.currentY = newPositionY; // Define if we need image drag
48990
48991    var scaledWidth = image.width * zoom.scale;
48992    var scaledHeight = image.height * zoom.scale;
48993    image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
48994    image.maxX = -image.minX;
48995    image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
48996    image.maxY = -image.minY;
48997    image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX);
48998    image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY);
48999    gesture.$imageWrapEl.transition(momentumDuration).transform("translate3d(" + image.currentX + "px, " + image.currentY + "px,0)");
49000  },
49001  onTransitionEnd: function onTransitionEnd() {
49002    var swiper = this;
49003    var zoom = swiper.zoom;
49004    var gesture = zoom.gesture;
49005
49006    if (gesture.$slideEl && swiper.previousIndex !== swiper.activeIndex) {
49007      if (gesture.$imageEl) {
49008        gesture.$imageEl.transform('translate3d(0,0,0) scale(1)');
49009      }
49010
49011      if (gesture.$imageWrapEl) {
49012        gesture.$imageWrapEl.transform('translate3d(0,0,0)');
49013      }
49014
49015      zoom.scale = 1;
49016      zoom.currentScale = 1;
49017      gesture.$slideEl = undefined;
49018      gesture.$imageEl = undefined;
49019      gesture.$imageWrapEl = undefined;
49020    }
49021  },
49022  // Toggle Zoom
49023  toggle: function toggle(e) {
49024    var swiper = this;
49025    var zoom = swiper.zoom;
49026
49027    if (zoom.scale && zoom.scale !== 1) {
49028      // Zoom Out
49029      zoom.out();
49030    } else {
49031      // Zoom In
49032      zoom.in(e);
49033    }
49034  },
49035  in: function _in(e) {
49036    var swiper = this;
49037    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
49038    var zoom = swiper.zoom;
49039    var params = swiper.params.zoom;
49040    var gesture = zoom.gesture,
49041        image = zoom.image;
49042
49043    if (!gesture.$slideEl) {
49044      if (e && e.target) {
49045        gesture.$slideEl = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(e.target).closest("." + swiper.params.slideClass);
49046      }
49047
49048      if (!gesture.$slideEl) {
49049        if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
49050          gesture.$slideEl = swiper.$wrapperEl.children("." + swiper.params.slideActiveClass);
49051        } else {
49052          gesture.$slideEl = swiper.slides.eq(swiper.activeIndex);
49053        }
49054      }
49055
49056      gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas, picture, .swiper-zoom-target');
49057      gesture.$imageWrapEl = gesture.$imageEl.parent("." + params.containerClass);
49058    }
49059
49060    if (!gesture.$imageEl || gesture.$imageEl.length === 0 || !gesture.$imageWrapEl || gesture.$imageWrapEl.length === 0) return;
49061    gesture.$slideEl.addClass("" + params.zoomedSlideClass);
49062    var touchX;
49063    var touchY;
49064    var offsetX;
49065    var offsetY;
49066    var diffX;
49067    var diffY;
49068    var translateX;
49069    var translateY;
49070    var imageWidth;
49071    var imageHeight;
49072    var scaledWidth;
49073    var scaledHeight;
49074    var translateMinX;
49075    var translateMinY;
49076    var translateMaxX;
49077    var translateMaxY;
49078    var slideWidth;
49079    var slideHeight;
49080
49081    if (typeof image.touchesStart.x === 'undefined' && e) {
49082      touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX;
49083      touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY;
49084    } else {
49085      touchX = image.touchesStart.x;
49086      touchY = image.touchesStart.y;
49087    }
49088
49089    zoom.scale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;
49090    zoom.currentScale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;
49091
49092    if (e) {
49093      slideWidth = gesture.$slideEl[0].offsetWidth;
49094      slideHeight = gesture.$slideEl[0].offsetHeight;
49095      offsetX = gesture.$slideEl.offset().left + window.scrollX;
49096      offsetY = gesture.$slideEl.offset().top + window.scrollY;
49097      diffX = offsetX + slideWidth / 2 - touchX;
49098      diffY = offsetY + slideHeight / 2 - touchY;
49099      imageWidth = gesture.$imageEl[0].offsetWidth;
49100      imageHeight = gesture.$imageEl[0].offsetHeight;
49101      scaledWidth = imageWidth * zoom.scale;
49102      scaledHeight = imageHeight * zoom.scale;
49103      translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);
49104      translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);
49105      translateMaxX = -translateMinX;
49106      translateMaxY = -translateMinY;
49107      translateX = diffX * zoom.scale;
49108      translateY = diffY * zoom.scale;
49109
49110      if (translateX < translateMinX) {
49111        translateX = translateMinX;
49112      }
49113
49114      if (translateX > translateMaxX) {
49115        translateX = translateMaxX;
49116      }
49117
49118      if (translateY < translateMinY) {
49119        translateY = translateMinY;
49120      }
49121
49122      if (translateY > translateMaxY) {
49123        translateY = translateMaxY;
49124      }
49125    } else {
49126      translateX = 0;
49127      translateY = 0;
49128    }
49129
49130    gesture.$imageWrapEl.transition(300).transform("translate3d(" + translateX + "px, " + translateY + "px,0
49130)");
49131    gesture.$imageEl.transition(300).transform("translate3d(0,0,0) scale(" + zoom.scale + ")");
49132  },
49133  out: function out() {
49134    var swiper = this;
49135    var zoom = swiper.zoom;
49136    var params = swiper.params.zoom;
49137    var gesture = zoom.gesture;
49138
49139    if (!gesture.$slideEl) {
49140      if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
49141        gesture.$slideEl = swiper.$wrapperEl.children("." + swiper.params.slideActiveClass);
49142      } else {
49143        gesture.$slideEl = swiper.slides.eq(swiper.activeIndex);
49144      }
49145
49146      gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas, picture, .swiper-zoom-target');
49147      gesture.$imageWrapEl = gesture.$imageEl.parent("." + params.containerClass);
49148    }
49149
49150    if (!gesture.$imageEl || gesture.$imageEl.length === 0 || !gesture.$imageWrapEl || gesture.$imageWrapEl.length === 0) return;
49151    zoom.scale = 1;
49152    zoom.currentScale = 1;
49153    gesture.$imageWrapEl.transition(300).transform('translate3d(0,0,0)');
49154    gesture.$imageEl.transition(300).transform('translate3d(0,0,0) scale(1)');
49155    gesture.$slideEl.removeClass("" + params.zoomedSlideClass);
49156    gesture.$slideEl = undefined;
49157  },
49158  toggleGestures: function toggleGestures(method) {
49159    var swiper = this;
49160    var zoom = swiper.zoom;
49161    var selector = zoom.slideSelector,
49162        passive = zoom.passiveListener;
49163    swiper.$wrapperEl[method]('gesturestart', selector, zoom.onGestureStart, passive);
49164    swiper.$wrapperEl[method]('gesturechange', selector, zoom.onGestureChange, passive);
49165    swiper.$wrapperEl[method]('gestureend', selector, zoom.onGestureEnd, passive);
49166  },
49167  enableGestures: function enableGestures() {
49168    if (this.zoom.gesturesEnabled) return;
49169    this.zoom.gesturesEnabled = true;
49170    this.zoom.toggleGestures('on');
49171  },
49172  disableGestures: function disableGestures() {
49173    if (!this.zoom.gesturesEnabled) return;
49174    this.zoom.gesturesEnabled = false;
49175    this.zoom.toggleGestures('off');
49176  },
49177  // Attach/Detach Events
49178  enable: function enable() {
49179    var swiper = this;
49180    var support = swiper.support;
49181    var zoom = swiper.zoom;
49182    if (zoom.enabled) return;
49183    zoom.enabled = true;
49184    var passiveListener = swiper.touchEvents.start === 'touchstart' && support.passiveListener && swiper.params.passiveListeners ? {
49185      passive: true,
49186      capture: false
49187    } : false;
49188    var activeListenerWithCapture = support.passiveListener ? {
49189      passive: false,
49190      capture: true
49191    } : true;
49192    var slideSelector = "." + swiper.params.slideClass;
49193    swiper.zoom.passiveListener = passiveListener;
49194    swiper.zoom.slideSelector = slideSelector; // Scale image
49195
49196    if (support.gestures) {
49197      swiper.$wrapperEl.on(swiper.touchEvents.start, swiper.zoom.enableGestures, passiveListener);
49198      swiper.$wrapperEl.on(swiper.touchEvents.end, swiper.zoom.disableGestures, passiveListener);
49199    } else if (swiper.touchEvents.start === 'touchstart') {
49200      swiper.$wrapperEl.on(swiper.touchEvents.start, slideSelector, zoom.onGestureStart, passiveListener);
49201      swiper.$wrapperEl.on(swiper.touchEvents.move, slideSelector, zoom.onGestureChange, activeListenerWithCapture);
49202      swiper.$wrapperEl.on(swiper.touchEvents.end, slideSelector, zoom.onGestureEnd, passiveListener);
49203
49204      if (swiper.touchEvents.cancel) {
49205        swiper.$wrapperEl.on(swiper.touchEvents.cancel, slideSelector, zoom.onGestureEnd, passiveListener);
49206      }
49207    } // Move image
49208
49209
49210    swiper.$wrapperEl.on(swiper.touchEvents.move, "." + swiper.params.zoom.containerClass, zoom.onTouchMove, activeListenerWithCapture);
49211  },
49212  disable: function disable() {
49213    var swiper = this;
49214    var zoom = swiper.zoom;
49215    if (!zoom.enabled) return;
49216    var support = swiper.support;
49217    swiper.zoom.enabled = false;
49218    var passiveListener = swiper.touchEvents.start === 'touchstart' && support.passiveListener && swiper.params.passiveListeners ? {
49219      passive: true,
49220      capture: false
49221    } : false;
49222    var activeListenerWithCapture = support.passiveListener ? {
49223      passive: false,
49224      capture: true
49225    } : true;
49226    var slideSelector = "." + swiper.params.slideClass; // Scale image
49227
49228    if (support.gestures) {
49229      swiper.$wrapperEl.off(swiper.touchEvents.start, swiper.zoom.enableGestures, passiveListener);
49230      swiper.$wrapperEl.off(swiper.touchEvents.end, swiper.zoom.disableGestures, passiveListener);
49231    } else if (swiper.touchEvents.start === 'touchstart') {
49232      swiper.$wrapperEl.off(swiper.touchEvents.start, slideSelector, zoom.onGestureStart, passiveListener);
49233      swiper.$wrapperEl.off(swiper.touchEvents.move, slideSelector, zoom.onGestureChange, activeListenerWithCapture);
49234      swiper.$wrapperEl.off(swiper.touchEvents.end, slideSelector, zoom.onGestureEnd, passiveListener);
49235
49236      if (swiper.touchEvents.cancel) {
49237        swiper.$wrapperEl.off(swiper.touchEvents.cancel, slideSelector, zoom.onGestureEnd, passiveListener);
49238      }
49239    } // Move image
49240
49241
49242    swiper.$wrapperEl.off(swiper.touchEvents.move, "." + swiper.params.zoom.containerClass, zoom.onTouchMove, activeListenerWithCapture);
49243  }
49244};
49245/* harmony default export */ __webpack_exports__["a"] = ({
49246  name: 'zoom',
49247  params: {
49248    zoom: {
49249      enabled: false,
49250      maxRatio: 3,
49251      minRatio: 1,
49252      toggle: true,
49253      containerClass: 'swiper-zoom-container',
49254      zoomedSlideClass: 'swiper-slide-zoomed'
49255    }
49256  },
49257  create: function create() {
49258    var swiper = this;
49259    Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["a" /* bindModuleMethods */])(swiper, {
49260      zoom: _extends({
49261        enabled: false,
49262        scale: 1,
49263        currentScale: 1,
49264        isScaling: false,
49265        gesture: {
49266          $slideEl: undefined,
49267          slideWidth: undefined,
49268          slideHeight: undefined,
49269          $imageEl: undefined,
49270          $imageWrapEl: undefined,
49271          maxRatio: 3
49272        },
49273        image: {
49274          isTouched: undefined,
49275          isMoved: undefined,
49276          currentX: undefined,
49277          currentY: undefined,
49278          minX: undefined,
49279          minY: undefined,
49280          maxX: undefined,
49281          maxY: undefined,
49282          width: undefined,
49283          height: undefined,
49284          startX: undefined,
49285          startY: undefined,
49286          touchesStart: {},
49287          touchesCurrent: {}
49288        },
49289        velocity: {
49290          x: undefined,
49291          y: undefined,
49292          prevPositionX: undefined,
49293          prevPositionY: undefined,
49294          prevTime: undefined
49295        }
49296      }, Zoom)
49297    });
49298    var scale = 1;
49299    Object.defineProperty(swiper.zoom, 'scale', {
49300      get: function get() {
49301        return scale;
49302      },
49303      set: function set(value) {
49304        if (scale !== value) {
49305          var imageEl = swiper.zoom.gesture.$imageEl ? swiper.zoom.gesture.$imageEl[0] : undefined;
49306          var slideEl = swiper.zoom.gesture.$slideEl ? swiper.zoom.gesture.$slideEl[0] : undefined;
49307          swiper.emit('zoomChange', value, imageEl, slideEl);
49308        }
49309
49310        scale = value;
49311      }
49312    });
49313  },
49314  on: {
49315    init: function init(swiper) {
49316      if (swiper.params.zoom.enabled) {
49317        swiper.zoom.enable();
49318      }
49319    },
49320    destroy: function destroy(swiper) {
49321      swiper.zoom.disable();
49322    },
49323    touchStart: function touchStart(swiper, e) {
49324      if (!swiper.zoom.enabled) return;
49325      swiper.zoom.onTouchStart(e);
49326    },
49327    touchEnd: function touchEnd(swiper, e) {
49328      if (!swiper.zoom.enabled) return;
49329      swiper.zoom.onTouchEnd(e);
49330    },
49331    doubleTap: function doubleTap(swiper, e) {
49332      if (!swiper.animating && swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) {
49333        swiper.zoom.toggle(e);
49334      }
49335    },
49336    transitionEnd: function transitionEnd(swiper) {
49337      if (swiper.zoom.enabled && swiper.params.zoom.enabled) {
49338        swiper.zoom.onTransitionEnd();
49339      }
49340    },
49341    slideChange: function slideChange(swiper) {
49342      if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) {
49343        swiper.zoom.onTransitionEnd();
49344      }
49345    }
49346  }
49347});
49348
49349/***/ }),
49350/* 240 */
49351/***/ (function(module, __webpack_exports__, __webpack_require__) {
49352
49353"use strict";
49354/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
49355/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_dom__ = __webpack_require__(3);
49356/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_utils__ = __webpack_require__(1);
49357function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
49358
49359
49360
49361
49362var Lazy = {
49363  loadInSlide: function loadInSlide(index, loadInDuplicate) {
49364    if (loadInDuplicate === void 0) {
49365      loadInDuplicate = true;
49366    }
49367
49368    var swiper = this;
49369    var params = swiper.params.lazy;
49370    if (typeof index === 'undefined') return;
49371    if (swiper.slides.length === 0) return;
49372    var isVirtual = swiper.virtual && swiper.params.virtual.enabled;
49373    var $slideEl = isVirtual ? swiper.$wrapperEl.children("." + swiper.params.slideClass + "[data-swiper-slide-index=\"" + index + "\"]") : swiper.slides.eq(index);
49374    var $images = $slideEl.find("." + params.elementClass + ":not(." + params.loadedClass + "):not(." + params.loadingClass + ")");
49375
49376    if ($slideEl.hasClass(params.elementClass) && !$slideEl.hasClass(params.loadedClass) && !$slideEl.hasClass(params.loadingClass)) {
49377      $images.push($slideEl[0]);
49378    }
49379
49380    if ($images.length === 0) return;
49381    $images.each(function (imageEl) {
49382      var $imageEl = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(imageEl);
49383      $imageEl.addClass(params.loadingClass);
49384      var background = $imageEl.attr('data-background');
49385      var src = $imageEl.attr('data-src');
49386      var srcset = $imageEl.attr('data-srcset');
49387      var sizes = $imageEl.attr('data-sizes');
49388      var $pictureEl = $imageEl.parent('picture');
49389      swiper.loadImage($imageEl[0], src || background, srcset, sizes, false, function () {
49390        if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper && !swiper.params || swiper.destroyed) return;
49391
49392        if (background) {
49393          $imageEl.css('background-image', "url(\"" + background + "\")");
49394          $imageEl.removeAttr('data-background');
49395        } else {
49396          if (srcset) {
49397            $imageEl.attr('srcset', srcset);
49398            $imageEl.removeAttr('data-srcset');
49399          }
49400
49401          if (sizes) {
49402            $imageEl.attr('sizes', sizes);
49403            $imageEl.removeAttr('data-sizes');
49404          }
49405
49406          if ($pictureEl.length) {
49407            $pictureEl.children('source').each(function (sourceEl) {
49408              var $source = Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(sourceEl);
49409
49410              if ($source.attr('data-srcset')) {
49411                $source.attr('srcset', $source.attr('data-srcset'));
49412                $source.removeAttr('data-srcset');
49413              }
49414            });
49415          }
49416
49417          if (src) {
49418            $imageEl.attr('src', src);
49419            $imageEl.removeAttr('data-src');
49420          }
49421        }
49422
49423        $imageEl.addClass(params.loadedClass).removeClass(params.loadingClass);
49424        $slideEl.find("." + params.preloaderClass).remove();
49425
49426        if (swiper.params.loop && loadInDuplicate) {
49427          var slideOriginalIndex = $slideEl.attr('data-swiper-slide-index');
49428
49429          if ($slideEl.hasClass(swiper.params.slideDuplicateClass)) {
49430            var originalSlide = swiper.$wrapperEl.children("[data-swiper-slide-index=\"" + slideOriginalIndex + "\"]:not(." + swiper.params.slideDuplicateClass + ")");
49431            swiper.lazy.loadInSlide(originalSlide.index(), false);
49432          } else {
49433            var duplicatedSlide = swiper.$wrapperEl.children("." + swiper.params.slideDuplicateClass + "[data-swiper-slide-index=\"" + slideOriginalIndex + "\"]");
49434            swiper.lazy.loadInSlide(duplicatedSlide.index(), false);
49435          }
49436        }
49437
49438        swiper.emit('lazyImageReady', $slideEl[0], $imageEl[0]);
49439
49440        if (swiper.params.autoHeight) {
49441          swiper.updateAutoHeight();
49442        }
49443      });
49444      swiper.emit('lazyImageLoad', $slideEl[0], $imageEl[0]);
49445    });
49446  },
49447  load: function load() {
49448    var swiper = this;
49449    var $wrapperEl = swiper.$wrapperEl,
49450        swiperParams = swiper.params,
49451        slides = swiper.slides,
49452        activeIndex = swiper.activeIndex;
49453    var isVirtual = swiper.virtual && swiperParams.virtual.enabled;
49454    var params = swiperParams.lazy;
49455    var slidesPerView = swiperParams.slidesPerView;
49456
49457    if (slidesPerView === 'auto') {
49458      slidesPerView = 0;
49459    }
49460
49461    function slideExist(index) {
49462      if (isVirtual) {
49463        if ($wrapperEl.children("." + swiperParams.slideClass + "[data-swiper-slide-index=\"" + index + "\"]").length) {
49464          return true;
49465        }
49466      } else if (slides[index]) return true;
49467
49468      return false;
49469    }
49470
49471    function slideIndex(slideEl) {
49472      if (isVirtual) {
49473        return Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(slideEl).attr('data-swiper-slide-index');
49474      }
49475
49476      return Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(slideEl).index();
49477    }
49478
49479    if (!swiper.lazy.initialImageLoaded) swiper.lazy.initialImageLoaded = true;
49480
49481    if (swiper.params.watchSlidesVisibility) {
49482      $wrapperEl.children("." + swiperParams.slideVisibleClass).each(function (slideEl) {
49483        var index = isVirtual ? Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(slideEl).attr('data-swiper-slide-index') : Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(slideEl).index();
49484        swiper.lazy.loadInSlide(index);
49485      });
49486    } else if (slidesPerView > 1) {
49487      for (var i = activeIndex; i < activeIndex + slidesPerView; i += 1) {
49488        if (slideExist(i)) swiper.lazy.loadInSlide(i);
49489      }
49490    } else {
49491      swiper.lazy.loadInSlide(activeIndex);
49492    }
49493
49494    if (params.loadPrevNext) {
49495      if (slidesPerView > 1 || params.loadPrevNextAmount && params.loadPrevNextAmount > 1) {
49496        var amount = params.loadPrevNextAmount;
49497        var spv = slidesPerView;
49498        var maxIndex = Math.min(activeIndex + spv + Math.max(amount, spv), slides.length);
49499        var minIndex = Math.max(activeIndex - Math.max(spv, amount), 0); // Next Slides
49500
49501        for (var _i = activeIndex + slidesPerView; _i < maxIndex; _i += 1) {
49502          if (slideExist(_i)) swiper.lazy.loadInSlide(_i);
49503        } // Prev Slides
49504
49505
49506        for (var _i2 = minIndex; _i2 < activeIndex; _i2 += 1) {
49507          if (slideExist(_i2)) swiper.lazy.loadInSlide(_i2);
49508        }
49509      } else {
49510        var nextSlide = $wrapperEl.children("." + swiperParams.slideNextClass);
49511        if (nextSlide.length > 0) swiper.lazy.loadInSlide(slideIndex(nextSlide));
49512        var prevSlide = $wrapperEl.children("." + swiperParams.slidePrevClass);
49513        if (prevSlide.length > 0) swiper.lazy.loadInSlide(slideIndex(prevSlide));
49514      }
49515    }
49516  },
49517  checkInViewOnLoad: function checkInViewOnLoad() {
49518    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
49519    var swiper = this;
49520    if (!swiper || swiper.destroyed) return;
49521    var $scrollElement = swiper.params.lazy.scrollingElement ? Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(swiper.params.lazy.scrollingElement) : Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(window);
49522    var isWindow = $scrollElement[0] === window;
49523    var scrollElementWidth = isWindow ? window.innerWidth : $scrollElement[0].offsetWidth;
49524    var scrollElementHeight = isWindow ? window.innerHeight : $scrollElement[0].offsetHeight;
49525    var swiperOffset = swiper.$el.offset();
49526    var rtl = swiper.rtlTranslate;
49527    var inView = false;
49528    if (rtl) swiperOffset.left -= swiper.$el[0].scrollLeft;
49529    var swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiper.width, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiper.height], [swiperOffset.left + swiper.width, swiperOffset.top + swiper.height]];
49530
49531    for (var i = 0; i < swiperCoord.length; i += 1) {
49532      var point = swiperCoord[i];
49533
49534      if (point[0] >= 0 && point[0] <= scrollElementWidth && point[1] >= 0 && point[1] <= scrollElementHeight) {
49535        if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line
49536
49537        inView = true;
49538      }
49539    }
49540
49541    var passiveListener = swiper.touchEvents.start === 'touchstart' && swiper.support.passiveListener && swiper.params.passiveListeners ? {
49542      passive: true,
49543      capture: false
49544    } : false;
49545
49546    if (inView) {
49547      swiper.lazy.load();
49548      $scrollElement.off('scroll', swiper.lazy.checkInViewOnLoad, passiveListener);
49549    } else if (!swiper.lazy.scrollHandlerAttached) {
49550      swiper.lazy.scrollHandlerAttached = true;
49551      $scrollElement.on('scroll', swiper.lazy.checkInViewOnLoad, passiveListener);
49552    }
49553  }
49554};
49555/* harmony default export */ __webpack_exports__["a"] = ({
49556  name: 'lazy',
49557  params: {
49558    lazy: {
49559      checkInView: false,
49560      enabled: false,
49561      loadPrevNext: false,
49562      loadPrevNextAmount: 1,
49563      loadOnTransitionStart: false,
49564      scrollingElement: '',
49565      elementClass: 'swiper-lazy',
49566      loadingClass: 'swiper-lazy-loading',
49567      loadedClass: 'swiper-lazy-loaded',
49568      preloaderClass: 'swiper-lazy-preloader'
49569    }
49570  },
49571  create: function create() {
49572    var swiper = this;
49573    Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["a" /* bindModuleMethods */])(swiper, {
49574      lazy: _extends({
49575        initialImageLoaded: false
49576      }, Lazy)
49577    });
49578  },
49579  on: {
49580    beforeInit: function beforeInit(swiper) {
49581      if (swiper.params.lazy.enabled && swiper.params.preloadImages) {
49582        swiper.params.preloadImages = false;
49583      }
49584    },
49585    init: function init(swiper) {
49586      if (swiper.params.lazy.enabled && !swiper.params.loop && swiper.params.initialSlide === 0) {
49587        if (swiper.params.lazy.checkInView) {
49588          swiper.lazy.checkInViewOnLoad();
49589        } else {
49590          swiper.lazy.load();
49591        }
49592      }
49593    },
49594    scroll: function scroll(swiper) {
49595      if (swiper.params.freeMode && !swiper.params.freeModeSticky) {
49596        swiper.lazy.load();
49597      }
49598    },
49599    'scrollbarDragMove resize _freeModeNoMomentumRelease': function lazyLoad(swiper) {
49600      if (swiper.params.lazy.enabled) {
49601        swiper.lazy.load();
49602      }
49603    },
49604    transitionStart: function transitionStart(swiper) {
49605      if (swiper.params.lazy.enabled) {
49606        if (swiper.params.lazy.loadOnTransitionStart || !swiper.params.lazy.loadOnTransitionStart && !swiper.lazy.initialImageLoaded) {
49607          swiper.lazy.load();
49608        }
49609      }
49610    },
49611    transitionEnd: function transitionEnd(swiper) {
49612      if (swiper.params.lazy.enabled && !swiper.params.lazy.loadOnTransitionStart) {
49613        swiper.lazy.load();
49614      }
49615    },
49616    slideChange: function slideChange(swiper) {
49617      var _swiper$params = swiper.params,
49618          lazy = _swiper$params.lazy,
49619          cssMode = _swiper$params.cssMode,
49620          watchSlidesVisibility = _swiper$params.watchSlidesVisibility,
49621          watchSlidesProgress = _swiper$params.watchSlidesProgress,
49622          touchReleaseOnEdges = _swiper$params.touchReleaseOnEdges,
49623          resistanceRatio = _swiper$params.resistanceRatio;
49624
49625      if (lazy.enabled && (cssMode || (watchSlidesVisibility || watchSlidesProgress) && (touchReleaseOnEdges || resistanceRatio === 0))) {
49626        swiper.lazy.load();
49627      }
49628    }
49629  }
49630});
49631
49632/***/ }),
49633/* 241 */
49634/***/ (function(module, __webpack_exports__, __webpack_require__) {
49635
49636"use strict";
49637/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_utils__ = __webpack_require__(1);
49638function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
49639
49640/* eslint no-bitwise: ["error", { "allow": [">>"] }] */
49641
49642var Controller = {
49643  LinearSpline: function LinearSpline(x, y) {
49644    var binarySearch = function search() {
49645      var maxIndex;
49646      var minIndex;
49647      var guess;
49648      return function (array, val) {
49649        minIndex = -1;
49650        maxIndex = array.length;
49651
49652        while (maxIndex - minIndex > 1) {
49653          guess = maxIndex + minIndex >> 1;
49654
49655          if (array[guess] <= val) {
49656            minIndex = guess;
49657          } else {
49658            maxIndex = guess;
49659          }
49660        }
49661
49662        return maxIndex;
49663      };
49664    }();
49665
49666    this.x = x;
49667    this.y = y;
49668    this.lastIndex = x.length - 1; // Given an x value (x2), return the expected y2 value:
49669    // (x1,y1) is the known point before given value,
49670    // (x3,y3) is the known point after given value.
49671
49672    var i1;
49673    var i3;
49674
49675    this.interpolate = function interpolate(x2) {
49676      if (!x2) return 0; // Get the indexes of x1 and x3 (the array indexes before and after given x2):
49677
49678      i3 = binarySearch(this.x, x2);
49679      i1 = i3 - 1; // We have our indexes i1 & i3, so we can calculate already:
49680      // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
49681
49682      return (x2 - this.x[i1]) * (this.y[i3] - this.y[i1]) / (this.x[i3] - this.x[i1]) + this.y[i1];
49683    };
49684
49685    return this;
49686  },
49687  // xxx: for now i will just save one spline function to to
49688  getInterpolateFunction: function getInterpolateFunction(c) {
49689    var swiper = this;
49690
49691    if (!swiper.controller.spline) {
49692      swiper.controller.spline = swiper.params.loop ? new Controller.LinearSpline(swiper.slidesGrid, c.slidesGrid) : new Controller.LinearSpline(swiper.snapGrid, c.snapGrid);
49693    }
49694  },
49695  setTranslate: function setTranslate(_setTranslate, byController) {
49696    var swiper = this;
49697    var controlled = swiper.controller.control;
49698    var multiplier;
49699    var controlledTranslate;
49700    var Swiper = swiper.constructor;
49701
49702    function setControlledTranslate(c) {
49703      // this will create an Interpolate function based on the snapGrids
49704      // x is the Grid of the scrolled scroller and y will be the controlled scroller
49705      // it makes sense to create this only once and recall it for the interpolation
49706      // the function does a lot of value caching for performance
49707      var translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate;
49708
49709      if (swiper.params.controller.by === 'slide') {
49710        swiper.controller.getInterpolateFunction(c); // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
49711        // but it did not work out
49712
49713        controlledTranslate = -swiper.controller.spline.interpolate(-translate);
49714      }
49715
49716      if (!controlledTranslate || swiper.params.controller.by === 'container') {
49717        multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate());
49718        controlledTranslate = (translate - swiper.minTranslate()) * multiplier + c.minTranslate();
49719      }
49720
49721      if (swiper.params.controller.inverse) {
49722        controlledTranslate = c.maxTranslate() - controlledTranslate;
49723      }
49724
49725      c.updateProgress(controlledTranslate);
49726      c.setTranslate(controlledTranslate, swiper);
49727      c.updateActiveIndex();
49728      c.updateSlidesClasses();
49729    }
49730
49731    if (Array.isArray(controlled)) {
49732      for (var i = 0; i < controlled.length; i += 1) {
49733        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
49734          setControlledTranslate(controlled[i]);
49735        }
49736      }
49737    } else if (controlled instanceof Swiper && byController !== controlled) {
49738      setControlledTranslate(controlled);
49739    }
49740  },
49741  setTransition: function setTransition(duration, byController) {
49742    var swiper = this;
49743    var Swiper = swiper.constructor;
49744    var controlled = swiper.controller.control;
49745    var i;
49746
49747    function setControlledTransition(c) {
49748      c.setTransition(duration, swiper);
49749
49750      if (duration !== 0) {
49751        c.transitionStart();
49752
49753        if (c.params.autoHeight) {
49754          Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["h" /* nextTick */])(function () {
49755            c.updateAutoHeight();
49756          });
49757        }
49758
49759        c.$wrapperEl.transitionEnd(function () {
49760          if (!controlled) return;
49761
49762          if (c.params.loop && swiper.params.controller.by === 'slide') {
49763            c.loopFix();
49764          }
49765
49766          c.transitionEnd();
49767        });
49768      }
49769    }
49770
49771    if (Array.isArray(controlled)) {
49772      for (i = 0; i < controlled.length; i += 1) {
49773        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
49774          setControlledTransition(controlled[i]);
49775        }
49776      }
49777    } else if (controlled instanceof Swiper && byController !== controlled) {
49778      setControlledTransition(controlled);
49779    }
49780  }
49781};
49782/* harmony default export */ __webpack_exports__["a"] = ({
49783  name: 'controller',
49784  params: {
49785    controller: {
49786      control: undefined,
49787      inverse: false,
49788      by: 'slide' // or 'container'
49789
49790    }
49791  },
49792  create: function create() {
49793    var swiper = this;
49794    Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["a" /* bindModuleMethods */])(swiper, {
49795      controller: _extends({
49796        control: swiper.params.controller.control
49797      }, Controller)
49798    });
49799  },
49800  on: {
49801    update: function update(swiper) {
49802      if (!swiper.controller.control) return;
49803
49804      if (swiper.controller.spline) {
49805        swiper.controller.spline = undefined;
49806        delete swiper.controller.spline;
49807      }
49808    },
49809    resize: function resize(swiper) {
49810      if (!swiper.controller.control) return;
49811
49812      if (swiper.controller.spline) {
49813        swiper.controller.spline = undefined;
49814        delete swiper.controller.spline;
49815      }
49816    },
49817    observerUpdate: function observerUpdate(swiper) {
49818      if (!swiper.controller.control) return;
49819
49820      if (swiper.controller.spline) {
49821        swiper.controller.spline = undefined;
49822        delete swiper.controller.spline;
49823      }
49824    },
49825    setTranslate: function setTranslate(swiper, translate, byController) {
49826      if (!swiper.controller.control) return;
49827      swiper.controller.setTranslate(translate, byController);
49828    },
49829    setTransition: function setTransition(swiper, duration, byController) {
49830      if (!swiper.controller.control) return;
49831      swiper.controller.setTransition(duration, byController);
49832    }
49833  }
49834});
49835
49836/***/ }),
49837/* 242 */
49838/***/ (function(module, __webpack_exports__, __webpack_require__) {
49839
49840"use strict";
49841/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_dom__ = __webpack_require__(3);
49842/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
49843function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
49844
49845
49846
49847var A11y = {
49848  getRandomNumber: function getRandomNumber(size) {
49849    if (size === void 0) {
49850      size = 16;
49851    }
49852
49853    var randomChar = function randomChar() {
49854      return Math.round(16 * Math.random()).toString(16);
49855    };
49856
49857    return 'x'.repeat(size).replace(/x/g, randomChar);
49858  },
49859  makeElFocusable: function makeElFocusable($el) {
49860    $el.attr('tabIndex', '0');
49861    return $el;
49862  },
49863  makeElNotFocusable: function makeElNotFocusable($el) {
49864    $el.attr('tabIndex', '-1');
49865    return $el;
49866  },
49867  addElRole: function addElRole($el, role) {
49868    $el.attr('role', role);
49869    return $el;
49870  },
49871  addElRoleDescription: function addElRoleDescription($el, description) {
49872    $el.attr('aria-roledescription', description);
49873    return $el;
49874  },
49875  addElControls: function addElControls($el, controls) {
49876    $el.attr('aria-controls', controls);
49877    return $el;
49878  },
49879  addElLabel: function addElLabel($el, label) {
49880    $el.attr('aria-label', label);
49881    return $el;
49882  },
49883  addElId: function addElId($el, id) {
49884    $el.attr('id', id);
49885    return $el;
49886  },
49887  addElLive: function addElLive($el, live) {
49888    $el.attr('aria-live', live);
49889    return $el;
49890  },
49891  disableEl: function disableEl($el) {
49892    $el.attr('aria-disabled', true);
49893    return $el;
49894  },
49895  enableEl: function enableEl($el) {
49896    $el.attr('aria-disabled', false);
49897    return $el;
49898  },
49899  onEnterOrSpaceKey: function onEnterOrSpaceKey(e) {
49900    if (e.keyCode !== 13 && e.keyCode !== 32) return;
49901    var swiper = this;
49902    var params = swiper.params.a11y;
49903    var $targetEl = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(e.target);
49904
49905    if (swiper.navigation && swiper.navigation.$nextEl && $targetEl.is(swiper.navigation.$nextEl)) {
49906      if (!(swiper.isEnd && !swiper.params.loop)) {
49907        swiper.slideNext();
49908      }
49909
49910      if (swiper.isEnd) {
49911        swiper.a11y.notify(params.lastSlideMessage);
49912      } else {
49913        swiper.a11y.notify(params.nextSlideMessage);
49914      }
49915    }
49916
49917    if (swiper.navigation && swiper.navigation.$prevEl && $targetEl.is(swiper.navigation.$prevEl)) {
49918      if (!(swiper.isBeginning && !swiper.params.loop)) {
49919        swiper.slidePrev();
49920      }
49921
49922      if (swiper.isBeginning) {
49923        swiper.a11y.notify(params.firstSlideMessage);
49924      } else {
49925        swiper.a11y.notify(params.prevSlideMessage);
49926      }
49927    }
49928
49929    if (swiper.pagination && $targetEl.is(Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["b" /* classesToSelector */])(swiper.params.pagination.bulletClass))) {
49930      $targetEl[0].click();
49931    }
49932  },
49933  notify: function notify(message) {
49934    var swiper = this;
49935    var notification = swiper.a11y.liveRegion;
49936    if (notification.length === 0) return;
49937    notification.html('');
49938    notification.html(message);
49939  },
49940  updateNavigation: function updateNavigation() {
49941    var swiper = this;
49942    if (swiper.params.loop || !swiper.navigation) return;
49943    var _swiper$navigation = swiper.navigation,
49944        $nextEl = _swiper$navigation.$nextEl,
49945        $prevEl = _swiper$navigation.$prevEl;
49946
49947    if ($prevEl && $prevEl.length > 0) {
49948      if (swiper.isBeginning) {
49949        swiper.a11y.disableEl($prevEl);
49950        swiper.a11y.makeElNotFocusable($prevEl);
49951      } else {
49952        swiper.a11y.enableEl($prevEl);
49953        swiper.a11y.makeElFocusable($prevEl);
49954      }
49955    }
49956
49957    if ($nextEl && $nextEl.length > 0) {
49958      if (swiper.isEnd) {
49959        swiper.a11y.disableEl($nextEl);
49960        swiper.a11y.makeElNotFocusable($nextEl);
49961      } else {
49962        swiper.a11y.enableEl($nextEl);
49963        swiper.a11y.makeElFocusable($nextEl);
49964      }
49965    }
49966  },
49967  updatePagination: function updatePagination() {
49968    var swiper = this;
49969    var params = swiper.params.a11y;
49970
49971    if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) {
49972      swiper.pagination.bullets.each(function (bulletEl) {
49973        var $bulletEl = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(bulletEl);
49974        swiper.a11y.makeElFocusable($bulletEl);
49975
49976        if (!swiper.params.pagination.renderBullet) {
49977          swiper.a11y.addElRole($bulletEl, 'button');
49978          swiper.a11y.addElLabel($bulletEl, params.paginationBulletMessage.replace(/\{\{index\}\}/, $bulletEl.index() + 1));
49979        }
49980      });
49981    }
49982  },
49983  init: function init() {
49984    var swiper = this;
49985    var params = swiper.params.a11y;
49986    swiper.$el.append(swiper.a11y.liveRegion); // Container
49987
49988    var $containerEl = swiper.$el;
49989
49990    if (params.containerRoleDescriptionMessage) {
49991      swiper.a11y.addElRoleDescription($containerEl, params.containerRoleDescriptionMessage);
49992    }
49993
49994    if (params.containerMessage) {
49995      swiper.a11y.addElLabel($containerEl, params.containerMessage);
49996    } // Wrapper
49997
49998
49999    var $wrapperEl = swiper.$wrapperEl;
50000    var wrapperId = $wrapperEl.attr('id') || "swiper-wrapper-" + swiper.a11y.getRandomNumber(16);
50001    var live = swiper.params.autoplay && swiper.params.autoplay.enabled ? 'off' : 'polite';
50002    swiper.a11y.addElId($wrapperEl, wrapperId);
50003    swiper.a11y.addElLive($wrapperEl, live); // Slide
50004
50005    if (params.itemRoleDescriptionMessage) {
50006      swiper.a11y.addElRoleDescription(Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(swiper.slides), params.itemRoleDescriptionMessage);
50007    }
50008
50009    swiper.a11y.addElRole(Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(swiper.slides), params.slideRole);
50010    var slidesLength = swiper.params.loop ? swiper.slides.filter(function (el) {
50011      return !el.classList.contains(swiper.params.slideDuplicateClass);
50012    }).length : swiper.slides.length;
50013    swiper.slides.each(function (slideEl, index) {
50014      var $slideEl = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])(slideEl);
50015      var slideIndex = swiper.params.loop ? parseInt($slideEl.attr('data-swiper-slide-index'), 10) : index;
50016      var ariaLabelMessage = params.slideLabelMessage.replace(/\{\{index\}\}/, slideIndex + 1).replace(/\{\{slidesLength\}\}/, slidesLength);
50017      swiper.a11y.addElLabel($slideEl, ariaLabelMessage);
50018    }); // Navigation
50019
50020    var $nextEl;
50021    var $prevEl;
50022
50023    if (swiper.navigation && swiper.navigation.$nextEl) {
50024      $nextEl = swiper.navigation.$nextEl;
50025    }
50026
50027    if (swiper.navigation && swiper.navigation.$prevEl) {
50028      $prevEl = swiper.navigation.$prevEl;
50029    }
50030
50031    if ($nextEl && $nextEl.length) {
50032      swiper.a11y.makeElFocusable($nextEl);
50033
50034      if ($nextEl[0].tagName !== 'BUTTON') {
50035        swiper.a11y.addElRole($nextEl, 'button');
50036        $nextEl.on('keydown', swiper.a11y.onEnterOrSpaceKey);
50037      }
50038
50039      swiper.a11y.addElLabel($nextEl, params.nextSlideMessage);
50040      swiper.a11y.addElControls($nextEl, wrapperId);
50041    }
50042
50043    if ($prevEl && $prevEl.length) {
50044      swiper.a11y.makeElFocusable($prevEl);
50045
50046      if ($prevEl[0].tagName !== 'BUTTON') {
50047        swiper.a11y.addElRole($prevEl, 'button');
50048        $prevEl.on('keydown', swiper.a11y.onEnterOrSpaceKey);
50049      }
50050
50051      swiper.a11y.addElLabel($prevEl, params.prevSlideMessage);
50052      swiper.a11y.addElControls($prevEl, wrapperId);
50053    } // Pagination
50054
50055
50056    if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) {
50057      swiper.pagination.$el.on('keydown', Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["b" /* classesToSelector */])(swiper.params.pagination.bulletClass), swiper.a11y.onEnterOrSpaceKey);
50058    }
50059  },
50060  destroy: function destroy() {
50061    var swiper = this;
50062    if (swiper.a11y.liveRegion && swiper.a11y.liveRegion.length > 0) swiper.a11y.liveRegion.remove();
50063    var $nextEl;
50064    var $prevEl;
50065
50066    if (swiper.navigation && swiper.navigation.$nextEl) {
50067      $nextEl = swiper.navigation.$nextEl;
50068    }
50069
50070    if (swiper.navigation && swiper.navigation.$prevEl) {
50071      $prevEl = swiper.navigation.$prevEl;
50072    }
50073
50074    if ($nextEl) {
50075      $nextEl.off('keydown', swiper.a11y.onEnterOrSpaceKey);
50076    }
50077
50078    if ($prevEl) {
50079      $prevEl.off('keydown', swiper.a11y.onEnterOrSpaceKey);
50080    } // Pagination
50081
50082
50083    if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) {
50084      swiper.pagination.$el.off('keydown', Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["b" /* classesToSelector */])(swiper.params.pagination.bulletClass), swiper.a11y.onEnterOrSpaceKey);
50085    }
50086  }
50087};
50088/* harmony default export */ __webpack_exports__["a"] = ({
50089  name: 'a11y',
50090  params: {
50091    a11y: {
50092      enabled: true,
50093      notificationClass: 'swiper-notification',
50094      prevSlideMessage: 'Previous slide',
50095      nextSlideMessage: 'Next slide',
50096      firstSlideMessage: 'This is the first slide',
50097      lastSlideMessage: 'This is the last slide',
50098      paginationBulletMessage: 'Go to slide {{index}}',
50099      slideLabelMessage: '{{index}} / {{slidesLength}}',
50100      containerMessage: null,
50101      containerRoleDescriptionMessage: null,
50102      itemRoleDescriptionMessage: null,
50103      slideRole: 'group'
50104    }
50105  },
50106  create: function create() {
50107    var swiper = this;
50108    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["a" /* bindModuleMethods */])(swiper, {
50109      a11y: _extends({}, A11y, {
50110        liveRegion: Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])("<span class=\"" + swiper.params.a11y.notificationClass + "\" aria-live=\"assertive\" aria-atomic=\"true\"></span>")
50111      })
50112    });
50113  },
50114  on: {
50115    afterInit: function afterInit(swiper) {
50116      if (!swiper.params.a11y.enabled) return;
50117      swiper.a11y.init();
50118      swiper.a11y.updateNavigation();
50119    },
50120    toEdge: function toEdge(swiper) {
50121      if (!swiper.params.a11y.enabled) return;
50122      swiper.a11y.updateNavigation();
50123    },
50124    fromEdge: function fromEdge(swiper) {
50125      if (!swiper.params.a11y.enabled) return;
50126      swiper.a11y.updateNavigation();
50127    },
50128    paginationUpdate: function paginationUpdate(swiper) {
50129      if (!swiper.params.a11y.enabled) return;
50130      swiper.a11y.updatePagination();
50131    },
50132    destroy: function destroy(swiper) {
50133      if (!swiper.params.a11y.enabled) return;
50134      swiper.a11y.destroy();
50135    }
50136  }
50137});
50138
50139/***/ }),
50140/* 243 */
50141/***/ (function(module, __webpack_exports__, __webpack_require__) {
50142
50143"use strict";
50144/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
50145/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
50146function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
50147
50148
50149
50150var History = {
50151  init: function init() {
50152    var swiper = this;
50153    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
50154    if (!swiper.params.history) return;
50155
50156    if (!window.history || !window.history.pushState) {
50157      swiper.params.history.enabled = false;
50158      swiper.params.hashNavigation.enabled = true;
50159      return;
50160    }
50161
50162    var history = swiper.history;
50163    history.initialized = true;
50164    history.paths = History.getPathValues(swiper.params.url);
50165    if (!history.paths.key && !history.paths.value) return;
50166    history.scrollToSlide(0, history.paths.value, swiper.params.runCallbacksOnInit);
50167
50168    if (!swiper.params.history.replaceState) {
50169      window.addEventListener('popstate', swiper.history.setHistoryPopState);
50170    }
50171  },
50172  destroy: function destroy() {
50173    var swiper = this;
50174    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
50175
50176    if (!swiper.params.history.replaceState) {
50177      window.removeEventListener('popstate', swiper.history.setHistoryPopState);
50178    }
50179  },
50180  setHistoryPopState: function setHistoryPopState() {
50181    var swiper = this;
50182    swiper.history.paths = History.getPathValues(swiper.params.url);
50183    swiper.history.scrollToSlide(swiper.params.speed, swiper.history.paths.value, false);
50184  },
50185  getPathValues: function getPathValues(urlOverride) {
50186    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
50187    var location;
50188
50189    if (urlOverride) {
50190      location = new URL(urlOverride);
50191    } else {
50192      location = window.location;
50193    }
50194
50195    var pathArray = location.pathname.slice(1).split('/').filter(function (part) {
50196      return part !== '';
50197    });
50198    var total = pathArray.length;
50199    var key = pathArray[total - 2];
50200    var value = pathArray[total - 1];
50201    return {
50202      key: key,
50203      value: value
50204    };
50205  },
50206  setHistory: function setHistory(key, index) {
50207    var swiper = this;
50208    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
50209    if (!swiper.history.initialized || !swiper.params.history.enabled) return;
50210    var location;
50211
50212    if (swiper.params.url) {
50213      location = new URL(swiper.params.url);
50214    } else {
50215      location = window.location;
50216    }
50217
50218    var slide = swiper.slides.eq(index);
50219    var value = History.slugify(slide.attr('data-history'));
50220
50221    if (swiper.params.history.root.length > 0) {
50222      var root = swiper.params.history.root;
50223      if (root[root.length - 1] === '/') root = root.slice(0, root.length - 1);
50224      value = root + "/" + key + "/" + value;
50225    } else if (!location.pathname.includes(key)) {
50226      value = key + "/" + value;
50227    }
50228
50229    var currentState = window.history.state;
50230
50231    if (currentState && currentState.value === value) {
50232      return;
50233    }
50234
50235    if (swiper.params.history.replaceState) {
50236      window.history.replaceState({
50237        value: value
50238      }, null, value);
50239    } else {
50240      window.history.pushState({
50241        value: value
50242      }, null, value);
50243    }
50244  },
50245  slugify: function slugify(text) {
50246    return text.toString().replace(/\s+/g, '-').replace(/[^\w-]+/g, '').replace(/--+/g, '-').replace(/^-+/, '').replace(/-+$/, '');
50247  },
50248  scrollToSlide: function scrollToSlide(speed, value, runCallbacks) {
50249    var swiper = this;
50250
50251    if (value) {
50252      for (var i = 0, length = swiper.slides.length; i < length; i += 1) {
50253        var slide = swiper.slides.eq(i);
50254        var slideHistory = History.slugify(slide.attr('data-history'));
50255
50256        if (slideHistory === value && !slide.hasClass(swiper.params.slideDuplicateClass)) {
50257          var index = slide.index();
50258          swiper.slideTo(index, speed, runCallbacks);
50259        }
50260      }
50261    } else {
50262      swiper.slideTo(0, speed, runCallbacks);
50263    }
50264  }
50265};
50266/* harmony default export */ __webpack_exports__["a"] = ({
50267  name: 'history',
50268  params: {
50269    history: {
50270      enabled: false,
50271      root: '',
50272      replaceState: false,
50273      key: 'slides'
50274    }
50275  },
50276  create: function create() {
50277    var swiper = this;
50278    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["a" /* bindModuleMethods */])(swiper, {
50279      history: _extends({}, History)
50280    });
50281  },
50282  on: {
50283    init: function init(swiper) {
50284      if (swiper.params.history.enabled) {
50285        swiper.history.init();
50286      }
50287    },
50288    destroy: function destroy(swiper) {
50289      if (swiper.params.history.enabled) {
50290        swiper.history.destroy();
50291      }
50292    },
50293    'transitionEnd _freeModeNoMomentumRelease': function transitionEnd_freeModeNoMomentumRelease(swiper) {
50294      if (swiper.history.initialized) {
50295        swiper.history.setHistory(swiper.params.history.key, swiper.activeIndex);
50296      }
50297    },
50298    slideChange: function slideChange(swiper) {
50299      if (swiper.history.initialized && swiper.params.cssMode) {
50300        swiper.history.setHistory(swiper.params.history.key, swiper.activeIndex);
50301      }
50302    }
50303  }
50304});
50305
50306/***/ }),
50307/* 244 */
50308/***/ (function(module, __webpack_exports__, __webpack_require__) {
50309
50310"use strict";
50311/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
50312/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_dom__ = __webpack_require__(3);
50313/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_utils__ = __webpack_require__(1);
50314function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
50315
50316
50317
50318
50319var HashNavigation = {
50320  onHashChange: function onHashChange() {
50321    var swiper = this;
50322    var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
50323    swiper.emit('hashChange');
50324    var newHash = document.location.hash.replace('#', '');
50325    var activeSlideHash = swiper.slides.eq(swiper.activeIndex).attr('data-hash');
50326
50327    if (newHash !== activeSlideHash) {
50328      var newIndex = swiper.$wrapperEl.children("." + swiper.params.slideClass + "[data-hash=\"" + newHash + "\"]").index();
50329      if (typeof newIndex === 'undefined') return;
50330      swiper.slideTo(newIndex);
50331    }
50332  },
50333  setHash: function setHash() {
50334    var swiper = this;
50335    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
50336    var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
50337    if (!swiper.hashNavigation.initialized || !swiper.params.hashNavigation.enabled) return;
50338
50339    if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) {
50340      window.history.replaceState(null, null, "#" + swiper.slides.eq(swiper.activeIndex).attr('data-hash') || '');
50341      swiper.emit('hashSet');
50342    } else {
50343      var slide = swiper.slides.eq(swiper.activeIndex);
50344      var hash = slide.attr('data-hash') || slide.attr('data-history');
50345      document.location.hash = hash || '';
50346      swiper.emit('hashSet');
50347    }
50348  },
50349  init: function init() {
50350    var swiper = this;
50351    var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
50352    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
50353    if (!swiper.params.hashNavigation.enabled || swiper.params.history && swiper.params.history.enabled) return;
50354    swiper.hashNavigation.initialized = true;
50355    var hash = document.location.hash.replace('#', '');
50356
50357    if (hash) {
50358      var speed = 0;
50359
50360      for (var i = 0, length = swiper.slides.length; i < length; i += 1) {
50361        var slide = swiper.slides.eq(i);
50362        var slideHash = slide.attr('data-hash') || slide.attr('data-history');
50363
50364        if (slideHash === hash && !slide.hasClass(swiper.params.slideDuplicateClass)) {
50365          var index = slide.index();
50366          swiper.slideTo(index, speed, swiper.params.runCallbacksOnInit, true);
50367        }
50368      }
50369    }
50370
50371    if (swiper.params.hashNavigation.watchState) {
50372      Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(window).on('hashchange', swiper.hashNavigation.onHashChange);
50373    }
50374  },
50375  destroy: function destroy() {
50376    var swiper = this;
50377    var window = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["b" /* getWindow */])();
50378
50379    if (swiper.params.hashNavigation.watchState) {
50380      Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(window).off('hashchange', swiper.hashNavigation.onHashChange);
50381    }
50382  }
50383};
50384/* harmony default export */ __webpack_exports__["a"] = ({
50385  name: 'hash-navigation',
50386  params: {
50387    hashNavigation: {
50388      enabled: false,
50389      replaceState: false,
50390      watchState: false
50391    }
50392  },
50393  create: function create() {
50394    var swiper = this;
50395    Object(__WEBPACK_IMPORTED_MODULE_2__utils_utils__["a" /* bindModuleMethods */])(swiper, {
50396      hashNavigation: _extends({
50397        initialized: false
50398      }, HashNavigation)
50399    });
50400  },
50401  on: {
50402    init: function init(swiper) {
50403      if (swiper.params.hashNavigation.enabled) {
50404        swiper.hashNavigation.init();
50405      }
50406    },
50407    destroy: function destroy(swiper) {
50408      if (swiper.params.hashNavigation.enabled) {
50409        swiper.hashNavigation.destroy();
50410      }
50411    },
50412    'transitionEnd _freeModeNoMomentumRelease': function transitionEnd_freeModeNoMomentumRelease(swiper) {
50413      if (swiper.hashNavigation.initialized) {
50414        swiper.hashNavigation.setHash();
50415      }
50416    },
50417    slideChange: function slideChange(swiper) {
50418      if (swiper.hashNavigation.initialized && swiper.params.cssMode) {
50419        swiper.hashNavigation.setHash();
50420      }
50421    }
50422  }
50423});
50424
50425/***/ }),
50426/* 245 */
50427/***/ (function(module, __webpack_exports__, __webpack_require__) {
50428
50429"use strict";
50430/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_ssr_window__ = __webpack_require__(4);
50431/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
50432function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
50433
50434/* eslint no-underscore-dangle: "off" */
50435
50436
50437var Autoplay = {
50438  run: function run() {
50439    var swiper = this;
50440    var $activeSlideEl = swiper.slides.eq(swiper.activeIndex);
50441    var delay = swiper.params.autoplay.delay;
50442
50443    if ($activeSlideEl.attr('data-swiper-autoplay')) {
50444      delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay;
50445    }
50446
50447    clearTimeout(swiper.autoplay.timeout);
50448    swiper.autoplay.timeout = Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["h" /* nextTick */])(function () {
50449      var autoplayResult;
50450
50451      if (swiper.params.autoplay.reverseDirection) {
50452        if (swiper.params.loop) {
50453          swiper.loopFix();
50454          autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
50455          swiper.emit('autoplay');
50456        } else if (!swiper.isBeginning) {
50457          autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
50458          swiper.emit('autoplay');
50459        } else if (!swiper.params.autoplay.stopOnLastSlide) {
50460          autoplayResult = swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true);
50461          swiper.emit('autoplay');
50462        } else {
50463          swiper.autoplay.stop();
50464        }
50465      } else if (swiper.params.loop) {
50466        swiper.loopFix();
50467        autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
50468        swiper.emit('autoplay');
50469      } else if (!swiper.isEnd) {
50470        autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
50471        swiper.emit('autoplay');
50472      } else if (!swiper.params.autoplay.stopOnLastSlide) {
50473        autoplayResult = swiper.slideTo(0, swiper.params.speed, true, true);
50474        swiper.emit('autoplay');
50475      } else {
50476        swiper.autoplay.stop();
50477      }
50478
50479      if (swiper.params.cssMode && swiper.autoplay.running) swiper.autoplay.run();else if (autoplayResult === false) {
50480        swiper.autoplay.run();
50481      }
50482    }, delay);
50483  },
50484  start: function start() {
50485    var swiper = this;
50486    if (typeof swiper.autoplay.timeout !== 'undefined') return false;
50487    if (swiper.autoplay.running) return false;
50488    swiper.autoplay.running = true;
50489    swiper.emit('autoplayStart');
50490    swiper.autoplay.run();
50491    return true;
50492  },
50493  stop: function stop() {
50494    var swiper = this;
50495    if (!swiper.autoplay.running) return false;
50496    if (typeof swiper.autoplay.timeout === 'undefined') return false;
50497
50498    if (swiper.autoplay.timeout) {
50499      clearTimeout(swiper.autoplay.timeout);
50500      swiper.autoplay.timeout = undefined;
50501    }
50502
50503    swiper.autoplay.running = false;
50504    swiper.emit('autoplayStop');
50505    return true;
50506  },
50507  pause: function pause(speed) {
50508    var swiper = this;
50509    if (!swiper.autoplay.running) return;
50510    if (swiper.autoplay.paused) return;
50511    if (swiper.autoplay.timeout) clearTimeout(swiper.autoplay.timeout);
50512    swiper.autoplay.paused = true;
50513
50514    if (speed === 0 || !swiper.params.autoplay.waitForTransition) {
50515      swiper.autoplay.paused = false;
50516      swiper.autoplay.run();
50517    } else {
50518      ['transitionend', 'webkitTransitionEnd'].forEach(function (event) {
50519        swiper.$wrapperEl[0].addEventListener(event, swiper.autoplay.onTransitionEnd);
50520      });
50521    }
50522  },
50523  onVisibilityChange: function onVisibilityChange() {
50524    var swiper = this;
50525    var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
50526
50527    if (document.visibilityState === 'hidden' && swiper.autoplay.running) {
50528      swiper.autoplay.pause();
50529    }
50530
50531    if (document.visibilityState === 'visible' && swiper.autoplay.paused) {
50532      swiper.autoplay.run();
50533      swiper.autoplay.paused = false;
50534    }
50535  },
50536  onTransitionEnd: function onTransitionEnd(e) {
50537    var swiper = this;
50538    if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return;
50539    if (e.target !== swiper.$wrapperEl[0]) return;
50540    ['transitionend', 'webkitTransitionEnd'].forEach(function (event) {
50541      swiper.$wrapperEl[0].removeEventListener(event, swiper.autoplay.onTransitionEnd);
50542    });
50543    swiper.autoplay.paused = false;
50544
50545    if (!swiper.autoplay.running) {
50546      swiper.autoplay.stop();
50547    } else {
50548      swiper.autoplay.run();
50549    }
50550  },
50551  onMouseEnter: function onMouseEnter() {
50552    var swiper = this;
50553
50554    if (swiper.params.autoplay.disableOnInteraction) {
50555      swiper.autoplay.stop();
50556    } else {
50557      swiper.autoplay.pause();
50558    }
50559
50560    ['transitionend', 'webkitTransitionEnd'].forEach(function (event) {
50561      swiper.$wrapperEl[0].removeEventListener(event, swiper.autoplay.onTransitionEnd);
50562    });
50563  },
50564  onMouseLeave: function onMouseLeave() {
50565    var swiper = this;
50566
50567    if (swiper.params.autoplay.disableOnInteraction) {
50568      return;
50569    }
50570
50571    swiper.autoplay.paused = false;
50572    swiper.autoplay.run();
50573  },
50574  attachMouseEvents: function attachMouseEvents() {
50575    var swiper = this;
50576
50577    if (swiper.params.autoplay.pauseOnMouseEnter) {
50578      swiper.$el.on('mouseenter', swiper.autoplay.onMouseEnter);
50579      swiper.$el.on('mouseleave', swiper.autoplay.onMouseLeave);
50580    }
50581  },
50582  detachMouseEvents: function detachMouseEvents() {
50583    var swiper = this;
50584    swiper.$el.off('mouseenter', swiper.autoplay.onMouseEnter);
50585    swiper.$el.off('mouseleave', swiper.autoplay.onMouseLeave);
50586  }
50587};
50588/* harmony default export */ __webpack_exports__["a"] = ({
50589  name: 'autoplay',
50590  params: {
50591    autoplay: {
50592      enabled: false,
50593      delay: 3000,
50594      waitForTransition: true,
50595      disableOnInteraction: true,
50596      stopOnLastSlide: false,
50597      reverseDirection: false,
50598      pauseOnMouseEnter: false
50599    }
50600  },
50601  create: function create() {
50602    var swiper = this;
50603    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["a" /* bindModuleMethods */])(swiper, {
50604      autoplay: _extends({}, Autoplay, {
50605        running: false,
50606        paused: false
50607      })
50608    });
50609  },
50610  on: {
50611    init: function init(swiper) {
50612      if (swiper.params.autoplay.enabled) {
50613        swiper.autoplay.start();
50614        var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
50615        document.addEventListener('visibilitychange', swiper.autoplay.onVisibilityChange);
50616        swiper.autoplay.attachMouseEvents();
50617      }
50618    },
50619    beforeTransitionStart: function beforeTransitionStart(swiper, speed, internal) {
50620      if (swiper.autoplay.running) {
50621        if (internal || !swiper.params.autoplay.disableOnInteraction) {
50622          swiper.autoplay.pause(speed);
50623        } else {
50624          swiper.autoplay.stop();
50625        }
50626      }
50627    },
50628    sliderFirstMove: function sliderFirstMove(swiper) {
50629      if (swiper.autoplay.running) {
50630        if (swiper.params.autoplay.disableOnInteraction) {
50631          swiper.autoplay.stop();
50632        } else {
50633          swiper.autoplay.pause();
50634        }
50635      }
50636    },
50637    touchEnd: function touchEnd(swiper) {
50638      if (swiper.params.cssMode && swiper.autoplay.paused && !swiper.params.autoplay.disableOnInteraction) {
50639        swiper.autoplay.run();
50640      }
50641    },
50642    destroy: function destroy(swiper) {
50643      swiper.autoplay.detachMouseEvents();
50644
50645      if (swiper.autoplay.running) {
50646        swiper.autoplay.stop();
50647      }
50648
50649      var document = Object(__WEBPACK_IMPORTED_MODULE_0_ssr_window__["a" /* getDocument */])();
50650      document.removeEventListener('visibilitychange', swiper.autoplay.onVisibilityChange);
50651    }
50652  }
50653});
50654
50655/***/ }),
50656/* 246 */
50657/***/ (function(module, __webpack_exports__, __webpack_require__) {
50658
50659"use strict";
50660/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_utils__ = __webpack_require__(1);
50661function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
50662
50663
50664var Fade = {
50665  setTranslate: function setTranslate() {
50666    var swiper = this;
50667    var slides = swiper.slides;
50668
50669    for (var i = 0; i < slides.length; i += 1) {
50670      var $slideEl = swiper.slides.eq(i);
50671      var offset = $slideEl[0].swiperSlideOffset;
50672      var tx = -offset;
50673      if (!swiper.params.virtualTranslate) tx -= swiper.translate;
50674      var ty = 0;
50675
50676      if (!swiper.isHorizontal()) {
50677        ty = tx;
50678        tx = 0;
50679      }
50680
50681      var slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs($slideEl[0].progress), 0) : 1 + Math.min(Math.max($slideEl[0].progress, -1), 0);
50682      $slideEl.css({
50683        opacity: slideOpacity
50684      }).transform("translate3d(" + tx + "px, " + ty + "px, 0px)");
50685    }
50686  },
50687  setTransition: function setTransition(duration) {
50688    var swiper = this;
50689    var slides = swiper.slides,
50690        $wrapperEl = swiper.$wrapperEl;
50691    slides.transition(duration);
50692
50693    if (swiper.params.virtualTranslate && duration !== 0) {
50694      var eventTriggered = false;
50695      slides.transitionEnd(function () {
50696        if (eventTriggered) return;
50697        if (!swiper || swiper.destroyed) return;
50698        eventTriggered = true;
50699        swiper.animating = false;
50700        var triggerEvents = ['webkitTransitionEnd', 'transitionend'];
50701
50702        for (var i = 0; i < triggerEvents.length; i += 1) {
50703          $wrapperEl.trigger(triggerEvents[i]);
50704        }
50705      });
50706    }
50707  }
50708};
50709/* harmony default export */ __webpack_exports__["a"] = ({
50710  name: 'effect-fade',
50711  params: {
50712    fadeEffect: {
50713      crossFade: false
50714    }
50715  },
50716  create: function create() {
50717    var swiper = this;
50718    Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["a" /* bindModuleMethods */])(swiper, {
50719      fadeEffect: _extends({}, Fade)
50720    });
50721  },
50722  on: {
50723    beforeInit: function beforeInit(swiper) {
50724      if (swiper.params.effect !== 'fade') return;
50725      swiper.classNames.push(swiper.params.containerModifierClass + "fade");
50726      var overwriteParams = {
50727        slidesPerView: 1,
50728        slidesPerColumn: 1,
50729        slidesPerGroup: 1,
50730        watchSlidesProgress: true,
50731        spaceBetween: 0,
50732        virtualTranslate: true
50733      };
50734      Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["e" /* extend */])(swiper.params, overwriteParams);
50735      Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["e" /* extend */])(swiper.originalParams, overwriteParams);
50736    },
50737    setTranslate: function setTranslate(swiper) {
50738      if (swiper.params.effect !== 'fade') return;
50739      swiper.fadeEffect.setTranslate();
50740    },
50741    setTransition: function setTransition(swiper, duration) {
50742      if (swiper.params.effect !== 'fade') return;
50743      swiper.fadeEffect.setTransition(duration);
50744    }
50745  }
50746});
50747
50748/***/ }),
50749/* 247 */
50750/***/ (function(module, __webpack_exports__, __webpack_require__) {
50751
50752"use strict";
50753/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_dom__ = __webpack_require__(3);
50754/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
50755function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
50756
50757
50758
50759var Cube = {
50760  setTranslate: function setTranslate() {
50761    var swiper = this;
50762    var $el = swiper.$el,
50763        $wrapperEl = swiper.$wrapperEl,
50764        slides = swiper.slides,
50765        swiperWidth = swiper.width,
50766        swiperHeight = swiper.height,
50767        rtl = swiper.rtlTranslate,
50768        swiperSize = swiper.size,
50769        browser = swiper.browser;
50770    var params = swiper.params.cubeEffect;
50771    var isHorizontal = swiper.isHorizontal();
50772    var isVirtual = swiper.virtual && swiper.params.virtual.enabled;
50773    var wrapperRotate = 0;
50774    var $cubeShadowEl;
50775
50776    if (params.shadow) {
50777      if (isHorizontal) {
50778        $cubeShadowEl = $wrapperEl.find('.swiper-cube-shadow');
50779
50780        if ($cubeShadowEl.length === 0) {
50781          $cubeShadowEl = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])('<div class="swiper-cube-shadow"></div>');
50782          $wrapperEl.append($cubeShadowEl);
50783        }
50784
50785        $cubeShadowEl.css({
50786          height: swiperWidth + "px"
50787        });
50788      } else {
50789        $cubeShadowEl = $el.find('.swiper-cube-shadow');
50790
50791        if ($cubeShadowEl.length === 0) {
50792          $cubeShadowEl = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])('<div class="swiper-cube-shadow"></div>');
50793          $el.append($cubeShadowEl);
50794        }
50795      }
50796    }
50797
50798    for (var i = 0; i < slides.length; i += 1) {
50799      var $slideEl = slides.eq(i);
50800      var slideIndex = i;
50801
50802      if (isVirtual) {
50803        slideIndex = parseInt($slideEl.attr('data-swiper-slide-index'), 10);
50804      }
50805
50806      var slideAngle = slideIndex * 90;
50807      var round = Math.floor(slideAngle / 360);
50808
50809      if (rtl) {
50810        slideAngle = -slideAngle;
50811        round = Math.floor(-slideAngle / 360);
50812      }
50813
50814      var progress = Math.max(Math.min($slideEl[0].progress, 1), -1);
50815      var tx = 0;
50816      var ty = 0;
50817      var tz = 0;
50818
50819      if (slideIndex % 4 === 0) {
50820        tx = -round * 4 * swiperSize;
50821        tz = 0;
50822      } else if ((slideIndex - 1) % 4 === 0) {
50823        tx = 0;
50824        tz = -round * 4 * swiperSize;
50825      } else if ((slideIndex - 2) % 4 === 0) {
50826        tx = swiperSize + round * 4 * swiperSize;
50827        tz = swiperSize;
50828      } else if ((slideIndex - 3) % 4 === 0) {
50829        tx = -swiperSize;
50830        tz = 3 * swiperSize + swiperSize * 4 * round;
50831      }
50832
50833      if (rtl) {
50834        tx = -tx;
50835      }
50836
50837      if (!isHorizontal) {
50838        ty = tx;
50839        tx = 0;
50840      }
50841
50842      var transform = "rotateX(" + (isHorizontal ? 0 : -slideAngle) + "deg) rotateY(" + (isHorizontal ? slideAngle : 0) + "deg) translate3d(" + tx + "px, " + ty + "px, " + tz + "px)";
50843
50844      if (progress <= 1 && progress > -1) {
50845        wrapperRotate = slideIndex * 90 + progress * 90;
50846        if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;
50847      }
50848
50849      $slideEl.transform(transform);
50850
50851      if (params.slideShadows) {
50852        // Set shadows
50853        var shadowBefore = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');
50854        var shadowAfter = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');
50855
50856        if (shadowBefore.length === 0) {
50857          shadowBefore = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])("<div class=\"swiper-slide-shadow-" + (isHorizontal ? 'left' : 'top') + "\"></div>");
50858          $slideEl.append(shadowBefore);
50859        }
50860
50861        if (shadowAfter.length === 0) {
50862          shadowAfter = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])("<div class=\"swiper-slide-shadow-" + (isHorizontal ? 'right' : 'bottom') + "\"></div>");
50863          $slideEl.append(shadowAfter);
50864        }
50865
50866        if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
50867        if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
50868      }
50869    }
50870
50871    $wrapperEl.css({
50872      '-webkit-transform-origin': "50% 50% -" + swiperSize / 2 + "px",
50873      '-moz-transform-origin': "50% 50% -" + swiperSize / 2 + "px",
50874      '-ms-transform-origin': "50% 50% -" + swiperSize / 2 + "px",
50875      'transform-origin': "50% 50% -" + swiperSize / 2 + "px"
50876    });
50877
50878    if (params.shadow) {
50879      if (isHorizontal) {
50880        $cubeShadowEl.transform("translate3d(0px, " + (swiperWidth / 2 + params.shadowOffset) + "px, " + -swiperWidth / 2 + "px) rotateX(90deg) rotateZ(0deg) scale(" + params.shadowScale + ")");
50881      } else {
50882        var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
50883        var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
50884        var scale1 = params.shadowScale;
50885        var scale2 = params.shadowScale / multiplier;
50886        var offset = params.shadowOffset;
50887        $cubeShadowEl.transform("scale3d(" + scale1 + ", 1, " + scale2 + ") translate3d(0px, " + (swiperHeight / 2 + offset) + "px, " + -swiperHeight / 2 / scale2 + "px) rotateX(-90deg)");
50888      }
50889    }
50890
50891    var zFactor = browser.isSafari || browser.isWebView ? -swiperSize / 2 : 0;
50892    $wrapperEl.transform("translate3d(0px,0," + zFactor + "px) rotateX(" + (swiper.isHorizontal() ? 0 : wrapperRotate) + "deg) rotateY(" + (swiper.isHorizontal() ? -wrapperRotate : 0) + "deg)");
50893  },
50894  setTransition: function setTransition(duration) {
50895    var swiper = this;
50896    var $el = swiper.$el,
50897        slides = swiper.slides;
50898    slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
50899
50900    if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {
50901      $el.find('.swiper-cube-shadow').transition(duration);
50902    }
50903  }
50904};
50905/* harmony default export */ __webpack_exports__["a"] = ({
50906  name: 'effect-cube',
50907  params: {
50908    cubeEffect: {
50909      slideShadows: true,
50910      shadow: true,
50911      shadowOffset: 20,
50912      shadowScale: 0.94
50913    }
50914  },
50915  create: function create() {
50916    var swiper = this;
50917    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["a" /* bindModuleMethods */])(swiper, {
50918      cubeEffect: _extends({}, Cube)
50919    });
50920  },
50921  on: {
50922    beforeInit: function beforeInit(swiper) {
50923      if (swiper.params.effect !== 'cube') return;
50924      swiper.classNames.push(swiper.params.containerModifierClass + "cube");
50925      swiper.classNames.push(swiper.params.containerModifierClass + "3d");
50926      var overwriteParams = {
50927        slidesPerView: 1,
50928        slidesPerColumn: 1,
50929        slidesPerGroup: 1,
50930        watchSlidesProgress: true,
50931        resistanceRatio: 0,
50932        spaceBetween: 0,
50933        centeredSlides: false,
50934        virtualTranslate: true
50935      };
50936      Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["e" /* extend */])(swiper.params, overwriteParams);
50937      Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["e" /* extend */])(swiper.originalParams, overwriteParams);
50938    },
50939    setTranslate: function setTranslate(swiper) {
50940      if (swiper.params.effect !== 'cube') return;
50941      swiper.cubeEffect.setTranslate();
50942    },
50943    setTransition: function setTransition(swiper, duration) {
50944      if (swiper.params.effect !== 'cube') return;
50945      swiper.cubeEffect.setTransition(duration);
50946    }
50947  }
50948});
50949
50950/***/ }),
50951/* 248 */
50952/***/ (function(module, __webpack_exports__, __webpack_require__) {
50953
50954"use strict";
50955/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_dom__ = __webpack_require__(3);
50956/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
50957function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
50958
50959
50960
50961var Flip = {
50962  setTranslate: function setTranslate() {
50963    var swiper = this;
50964    var slides = swiper.slides,
50965        rtl = swiper.rtlTranslate;
50966
50967    for (var i = 0; i < slides.length; i += 1) {
50968      var $slideEl = slides.eq(i);
50969      var progress = $slideEl[0].progress;
50970
50971      if (swiper.params.flipEffect.limitRotation) {
50972        progress = Math.max(Math.min($slideEl[0].progress, 1), -1);
50973      }
50974
50975      var offset = $slideEl[0].swiperSlideOffset;
50976      var rotate = -180 * progress;
50977      var rotateY = rotate;
50978      var rotateX = 0;
50979      var tx = -offset;
50980      var ty = 0;
50981
50982      if (!swiper.isHorizontal()) {
50983        ty = tx;
50984        tx = 0;
50985        rotateX = -rotateY;
50986        rotateY = 0;
50987      } else if (rtl) {
50988        rotateY = -rotateY;
50989      }
50990
50991      $slideEl[0].style.zIndex = -Math.abs(Math.round(progress)) + slides.length;
50992
50993      if (swiper.params.flipEffect.slideShadows) {
50994        // Set shadows
50995        var shadowBefore = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');
50996        var shadowAfter = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');
50997
50998        if (shadowBefore.length === 0) {
50999          shadowBefore = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])("<div class=\"swiper-slide-shadow-" + (swiper.isHorizontal() ? 'left' : 'top') + "\"></div>");
51000          $slideEl.append(shadowBefore);
51001        }
51002
51003        if (shadowAfter.length === 0) {
51004          shadowAfter = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])("<div class=\"swiper-slide-shadow-" + (swiper.isHorizontal() ? 'right' : 'bottom') + "\"></div>");
51005          $slideEl.append(shadowAfter);
51006        }
51007
51008        if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
51009        if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
51010      }
51011
51012      $slideEl.transform("translate3d(" + tx + "px, " + ty + "px, 0px) rotateX(" + rotateX + "deg) rotateY(" + rotateY + "deg)");
51013    }
51014  },
51015  setTransition: function setTransition(duration) {
51016    var swiper = this;
51017    var slides = swiper.slides,
51018        activeIndex = swiper.activeIndex,
51019        $wrapperEl = swiper.$wrapperEl;
51020    slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
51021
51022    if (swiper.params.virtualTranslate && duration !== 0) {
51023      var eventTriggered = false; // eslint-disable-next-line
51024
51025      slides.eq(activeIndex).transitionEnd(function onTransitionEnd() {
51026        if (eventTriggered) return;
51027        if (!swiper || swiper.destroyed) return; // if (!$(this).hasClass(swiper.params.slideActiveClass)) return;
51028
51029        eventTriggered = true;
51030        swiper.animating = false;
51031        var triggerEvents = ['webkitTransitionEnd', 'transitionend'];
51032
51033        for (var i = 0; i < triggerEvents.length; i += 1) {
51034          $wrapperEl.trigger(triggerEvents[i]);
51035        }
51036      });
51037    }
51038  }
51039};
51040/* harmony default export */ __webpack_exports__["a"] = ({
51041  name: 'effect-flip',
51042  params: {
51043    flipEffect: {
51044      slideShadows: true,
51045      limitRotation: true
51046    }
51047  },
51048  create: function create() {
51049    var swiper = this;
51050    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["a" /* bindModuleMethods */])(swiper, {
51051      flipEffect: _extends({}, Flip)
51052    });
51053  },
51054  on: {
51055    beforeInit: function beforeInit(swiper) {
51056      if (swiper.params.effect !== 'flip') return;
51057      swiper.classNames.push(swiper.params.containerModifierClass + "flip");
51058      swiper.classNames.push(swiper.params.containerModifierClass + "3d");
51059      var overwriteParams = {
51060        slidesPerView: 1,
51061        slidesPerColumn: 1,
51062        slidesPerGroup: 1,
51063        watchSlidesProgress: true,
51064        spaceBetween: 0,
51065        virtualTranslate: true
51066      };
51067      Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["e" /* extend */])(swiper.params, overwriteParams);
51068      Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["e" /* extend */])(swiper.originalParams, overwriteParams);
51069    },
51070    setTranslate: function setTranslate(swiper) {
51071      if (swiper.params.effect !== 'flip') return;
51072      swiper.flipEffect.setTranslate();
51073    },
51074    setTransition: function setTransition(swiper, duration) {
51075      if (swiper.params.effect !== 'flip') return;
51076      swiper.flipEffect.setTransition(duration);
51077    }
51078  }
51079});
51080
51081/***/ }),
51082/* 249 */
51083/***/ (function(module, __webpack_exports__, __webpack_require__) {
51084
51085"use strict";
51086/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_dom__ = __webpack_require__(3);
51087/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_utils__ = __webpack_require__(1);
51088function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
51089
51090
51091
51092var Coverflow = {
51093  setTranslate: function setTranslate() {
51094    var swiper = this;
51095    var swiperWidth = swiper.width,
51096        swiperHeight = swiper.height,
51097        slides = swiper.slides,
51098        slidesSizesGrid = swiper.slidesSizesGrid;
51099    var params = swiper.params.coverflowEffect;
51100    var isHorizontal = swiper.isHorizontal();
51101    var transform = swiper.translate;
51102    var center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;
51103    var rotate = isHorizontal ? params.rotate : -params.rotate;
51104    var translate = params.depth; // Each slide offset from center
51105
51106    for (var i = 0, length = slides.length; i < length; i += 1) {
51107      var $slideEl = slides.eq(i);
51108      var slideSize = slidesSizesGrid[i];
51109      var slideOffset = $slideEl[0].swiperSlideOffset;
51110      var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * params.modifier;
51111      var rotateY = isHorizontal ? rotate * offsetMultiplier : 0;
51112      var rotateX = isHorizontal ? 0 : rotate * offsetMultiplier; // var rotateZ = 0
51113
51114      var translateZ = -translate * Math.abs(offsetMultiplier);
51115      var stretch = params.stretch; // Allow percentage to make a relative stretch for responsive sliders
51116
51117      if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {
51118        stretch = parseFloat(params.stretch) / 100 * slideSize;
51119      }
51120
51121      var translateY = isHorizontal ? 0 : stretch * offsetMultiplier;
51122      var translateX = isHorizontal ? stretch * offsetMultiplier : 0;
51123      var scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier); // Fix for ultra small values
51124
51125      if (Math.abs(translateX) < 0.001) translateX = 0;
51126      if (Math.abs(translateY) < 0.001) translateY = 0;
51127      if (Math.abs(translateZ) < 0.001) translateZ = 0;
51128      if (Math.abs(rotateY) < 0.001) rotateY = 0;
51129      if (Math.abs(rotateX) < 0.001) rotateX = 0;
51130      if (Math.abs(scale) < 0.001) scale = 0;
51131      var slideTransform = "translate3d(" + translateX + "px," + translateY + "px," + translateZ + "px)  rotateX(" + rotateX + "deg) rotateY(" + rotateY + "deg) scale(" + scale + ")";
51132      $slideEl.transform(slideTransform);
51133      $slideEl[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
51134
51135      if (params.slideShadows) {
51136        // Set shadows
51137        var $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');
51138        var $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');
51139
51140        if ($shadowBeforeEl.length === 0) {
51141          $shadowBeforeEl = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])("<div class=\"swiper-slide-shadow-" + (isHorizontal ? 'left' : 'top') + "\"></div>");
51142          $slideEl.append($shadowBeforeEl);
51143        }
51144
51145        if ($shadowAfterEl.length === 0) {
51146          $shadowAfterEl = Object(__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */])("<div class=\"swiper-slide-shadow-" + (isHorizontal ? 'right' : 'bottom') + "\"></div>");
51147          $slideEl.append($shadowAfterEl);
51148        }
51149
51150        if ($shadowBeforeEl.length) $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
51151        if ($shadowAfterEl.length) $shadowAfterEl[0].style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;
51152      }
51153    }
51154  },
51155  setTransition: function setTransition(duration) {
51156    var swiper = this;
51157    swiper.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
51158  }
51159};
51160/* harmony default export */ __webpack_exports__["a"] = ({
51161  name: 'effect-coverflow',
51162  params: {
51163    coverflowEffect: {
51164      rotate: 50,
51165      stretch: 0,
51166      depth: 100,
51167      scale: 1,
51168      modifier: 1,
51169      slideShadows: true
51170    }
51171  },
51172  create: function create() {
51173    var swiper = this;
51174    Object(__WEBPACK_IMPORTED_MODULE_1__utils_utils__["a" /* bindModuleMethods */])(swiper, {
51175      coverflowEffect: _extends({}, Coverflow)
51176    });
51177  },
51178  on: {
51179    beforeInit: function beforeInit(swiper) {
51180      if (swiper.params.effect !== 'coverflow') return;
51181      swiper.classNames.push(swiper.params.containerModifierClass + "coverflow");
51182      swiper.classNames.push(swiper.params.containerModifierClass + "3d");
51183      swiper.params.watchSlidesProgress = true;
51184      swiper.originalParams.watchSlidesProgress = true;
51185    },
51186    setTranslate: function setTranslate(swiper) {
51187      if (swiper.params.effect !== 'coverflow') return;
51188      swiper.coverflowEffect.setTranslate();
51189    },
51190    setTransition: function setTransition(swiper, duration) {
51191      if (swiper.params.effect !== 'coverflow') return;
51192      swiper.coverflowEffect.setTransition(duration);
51193    }
51194  }
51195});
51196
51197/***/ }),
51198/* 250 */
51199/***/ (function(module, __webpack_exports__, __webpack_require__) {
51200
51201"use strict";
51202/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_utils__ = __webpack_require__(1);
51203/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_dom__ = __webpack_require__(3);
51204function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
51205
51206
51207
51208var Thumbs = {
51209  init: function init() {
51210    var swiper = this;
51211    var thumbsParams = swiper.params.thumbs;
51212    if (swiper.thumbs.initialized) return false;
51213    swiper.thumbs.initialized = true;
51214    var SwiperClass = swiper.constructor;
51215
51216    if (thumbsParams.swiper instanceof SwiperClass) {
51217      swiper.thumbs.swiper = thumbsParams.swiper;
51218      Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["e" /* extend */])(swiper.thumbs.swiper.originalParams, {
51219        watchSlidesProgress: true,
51220        slideToClickedSlide: false
51221      });
51222      Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["e" /* extend */])(swiper.thumbs.swiper.params, {
51223        watchSlidesProgress: true,
51224        slideToClickedSlide: false
51225      });
51226    } else if (Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["g" /* isObject */])(thumbsParams.swiper)) {
51227      swiper.thumbs.swiper = new SwiperClass(Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["e" /* extend */])({}, thumbsParams.swiper, {
51228        watchSlidesVisibility: true,
51229        watchSlidesProgress: true,
51230        slideToClickedSlide: false
51231      }));
51232      swiper.thumbs.swiperCreated = true;
51233    }
51234
51235    swiper.thumbs.swiper.$el.addClass(swiper.params.thumbs.thumbsContainerClass);
51236    swiper.thumbs.swiper.on('tap', swiper.thumbs.onThumbClick);
51237    return true;
51238  },
51239  onThumbClick: function onThumbClick() {
51240    var swiper = this;
51241    var thumbsSwiper = swiper.thumbs.swiper;
51242    if (!thumbsSwiper) return;
51243    var clickedIndex = thumbsSwiper.clickedIndex;
51244    var clickedSlide = thumbsSwiper.clickedSlide;
51245    if (clickedSlide && Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(clickedSlide).hasClass(swiper.params.thumbs.slideThumbActiveClass)) return;
51246    if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;
51247    var slideToIndex;
51248
51249    if (thumbsSwiper.params.loop) {
51250      slideToIndex = parseInt(Object(__WEBPACK_IMPORTED_MODULE_1__utils_dom__["a" /* default */])(thumbsSwiper.clickedSlide).attr('data-swiper-slide-index'), 10);
51251    } else {
51252      slideToIndex = clickedIndex;
51253    }
51254
51255    if (swiper.params.loop) {
51256      var currentIndex = swiper.activeIndex;
51257
51258      if (swiper.slides.eq(currentIndex).hasClass(swiper.params.slideDuplicateClass)) {
51259        swiper.loopFix(); // eslint-disable-next-line
51260
51261        swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
51262        currentIndex = swiper.activeIndex;
51263      }
51264
51265      var prevIndex = swiper.slides.eq(currentIndex).prevAll("[data-swiper-slide-index=\"" + slideToIndex + "\"]").eq(0).index();
51266      var nextIndex = swiper.slides.eq(currentIndex).nextAll("[data-swiper-slide-index=\"" + slideToIndex + "\"]").eq(0).index();
51267      if (typeof prevIndex === 'undefined') slideToIndex = nextIndex;else if (typeof nextIndex === 'undefined') slideToIndex = prevIndex;else if (nextIndex - currentIndex < currentIndex - prevIndex) slideToIndex = nextIndex;else slideToIndex = prevIndex;
51268    }
51269
51270    swiper.slideTo(slideToIndex);
51271  },
51272  update: function update(initial) {
51273    var swiper = this;
51274    var thumbsSwiper = swiper.thumbs.swiper;
51275    if (!thumbsSwiper) return;
51276    var slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' ? thumbsSwiper.slidesPerViewDynamic() : thumbsSwiper.params.slidesPerView;
51277    var autoScrollOffset = swiper.params.thumbs.autoScrollOffset;
51278    var useOffset = autoScrollOffset && !thumbsSwiper.params.loop;
51279
51280    if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {
51281      var currentThumbsIndex = thumbsSwiper.activeIndex;
51282      var newThumbsIndex;
51283      var direction;
51284
51285      if (thumbsSwiper.params.loop) {
51286        if (thumbsSwiper.slides.eq(currentThumbsIndex).hasClass(thumbsSwiper.params.slideDuplicateClass)) {
51287          thumbsSwiper.loopFix(); // eslint-disable-next-line
51288
51289          thumbsSwiper._clientLeft = thumbsSwiper.$wrapperEl[0].clientLeft;
51290          currentThumbsIndex = thumbsSwiper.activeIndex;
51291        } // Find actual thumbs index to slide to
51292
51293
51294        var prevThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).prevAll("[data-swiper-slide-index=\"" + swiper.realIndex + "\"]").eq(0).index();
51295        var nextThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).nextAll("[data-swiper-slide-index=\"" + swiper.realIndex + "\"]").eq(0).index();
51296
51297        if (typeof prevThumbsIndex === 'undefined') {
51298          newThumbsIndex = nextThumbsIndex;
51299        } else if (typeof nextThumbsIndex === 'undefined') {
51300          newThumbsIndex = prevThumbsIndex;
51301        } else if (nextThumbsIndex - currentThumbsIndex === currentThumbsIndex - prevThumbsIndex) {
51302          newThumbsIndex = thumbsSwiper.params.slidesPerGroup > 1 ? nextThumbsIndex : currentThumbsIndex;
51303        } else if (nextThumbsIndex - currentThumbsIndex < currentThumbsIndex - prevThumbsIndex) {
51304          newThumbsIndex = nextThumbsIndex;
51305        } else {
51306          newThumbsIndex = prevThumbsIndex;
51307        }
51308
51309        direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';
51310      } else {
51311        newThumbsIndex = swiper.realIndex;
51312        direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';
51313      }
51314
51315      if (useOffset) {
51316        newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;
51317      }
51318
51319      if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) {
51320        if (thumbsSwiper.params.centeredSlides) {
51321          if (newThumbsIndex > currentThumbsIndex) {
51322            newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;
51323          } else {
51324            newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;
51325          }
51326        } else if (newThumbsIndex > currentThumbsIndex && thumbsSwiper.params.slidesPerGroup === 1) {// newThumbsIndex = newThumbsIndex - slidesPerView + 1;
51327        }
51328
51329        thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);
51330      }
51331    } // Activate thumbs
51332
51333
51334    var thumbsToActivate = 1;
51335    var thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;
51336
51337    if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {
51338      thumbsToActivate = swiper.params.slidesPerView;
51339    }
51340
51341    if (!swiper.params.thumbs.multipleActiveThumbs) {
51342      thumbsToActivate = 1;
51343    }
51344
51345    thumbsToActivate = Math.floor(thumbsToActivate);
51346    thumbsSwiper.slides.removeClass(thumbActiveClass);
51347
51348    if (thumbsSwiper.params.loop || thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled) {
51349      for (var i = 0; i < thumbsToActivate; i += 1) {
51350        thumbsSwiper.$wrapperEl.children("[data-swiper-slide-index=\"" + (swiper.realIndex + i) + "\"]").addClass(thumbActiveClass);
51351      }
51352    } else {
51353      for (var _i = 0; _i < thumbsToActivate; _i += 1) {
51354        thumbsSwiper.slides.eq(swiper.realIndex + _i).addClass(thumbActiveClass);
51355      }
51356    }
51357  }
51358};
51359/* harmony default export */ __webpack_exports__["a"] = ({
51360  name: 'thumbs',
51361  params: {
51362    thumbs: {
51363      swiper: null,
51364      multipleActiveThumbs: true,
51365      autoScrollOffset: 0,
51366      slideThumbActiveClass: 'swiper-slide-thumb-active',
51367      thumbsContainerClass: 'swiper-container-thumbs'
51368    }
51369  },
51370  create: function create() {
51371    var swiper = this;
51372    Object(__WEBPACK_IMPORTED_MODULE_0__utils_utils__["a" /* bindModuleMethods */])(swiper, {
51373      thumbs: _extends({
51374        swiper: null,
51375        initialized: false
51376      }, Thumbs)
51377    });
51378  },
51379  on: {
51380    beforeInit: function beforeInit(swiper) {
51381      var thumbs = swiper.params.thumbs;
51382      if (!thumbs || !thumbs.swiper) return;
51383      swiper.thumbs.init();
51384      swiper.thumbs.update(true);
51385    },
51386    slideChange: function slideChange(swiper) {
51387      if (!swiper.thumbs.swiper) return;
51388      swiper.thumbs.update();
51389    },
51390    update: function update(swiper) {
51391      if (!swiper.thumbs.swiper) return;
51392      swiper.thumbs.update();
51393    },
51394    resize: function resize(swiper) {
51395      if (!swiper.thumbs.swiper) return;
51396      swiper.thumbs.update();
51397    },
51398    observerUpdate: function observerUpdate(swiper) {
51399      if (!swiper.thumbs.swiper) return;
51400      swiper.thumbs.update();
51401    },
51402    setTransition: function setTransition(swiper, duration) {
51403      var thumbsSwiper = swiper.thumbs.swiper;
51404      if (!thumbsSwiper) return;
51405      thumbsSwiper.setTransition(duration);
51406    },
51407    beforeDestroy: function beforeDestroy(swiper) {
51408      var thumbsSwiper = swiper.thumbs.swiper;
51409      if (!thumbsSwiper) return;
51410
51411      if (swiper.thumbs.swiperCreated && thumbsSwiper) {
51412        thumbsSwiper.destroy();
51413      }
51414    }
51415  }
51416});
51417
51418/***/ }),
51419/* 251 */
51420/***/ (function(module, exports, __webpack_require__) {
51421
51422var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
51423 * imagesLoaded v4.1.4
51424 * JavaScript is all like "You images are done yet or what?"
51425 * MIT License
51426 */
51427
51428( function( window, factory ) { 'use strict';
51429  // universal module definition
51430
51431  /*global define: false, module: false, require: false */
51432
51433  if ( true ) {
51434    // AMD
51435    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
51436      __webpack_require__(8)
51437    ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( EvEmitter ) {
51438      return factory( window, EvEmitter );
51439    }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
51440				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
51441  } else if ( typeof module == 'object' && module.exports ) {
51442    // CommonJS
51443    module.exports = factory(
51444      window,
51445      require('ev-emitter')
51446    );
51447  } else {
51448    // browser global
51449    window.imagesLoaded = factory(
51450      window,
51451      window.EvEmitter
51452    );
51453  }
51454
51455})( typeof window !== 'undefined' ? window : this,
51456
51457// --------------------------  factory -------------------------- //
51458
51459function factory( window, EvEmitter ) {
51460
51461'use strict';
51462
51463var $ = window.jQuery;
51464var console = window.console;
51465
51466// -------------------------- helpers -------------------------- //
51467
51468// extend objects
51469function extend( a, b ) {
51470  for ( var prop in b ) {
51471    a[ prop ] = b[ prop ];
51472  }
51473  return a;
51474}
51475
51476var arraySlice = Array.prototype.slice;
51477
51478// turn element or nodeList into an array
51479function makeArray( obj ) {
51480  if ( Array.isArray( obj ) ) {
51481    // use object if already an array
51482    return obj;
51483  }
51484
51485  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
51486  if ( isArrayLike ) {
51487    // convert nodeList to array
51488    return arraySlice.call( obj );
51489  }
51490
51491  // array of single index
51492  return [ obj ];
51493}
51494
51495// -------------------------- imagesLoaded -------------------------- //
51496
51497/**
51498 * @param {Array, Element, NodeList, String} elem
51499 * @param {Object or Function} options - if function, use as callback
51500 * @param {Function} onAlways - callback function
51501 */
51502function ImagesLoaded( elem, options, onAlways ) {
51503  // coerce ImagesLoaded() without new, to be new ImagesLoaded()
51504  if ( !( this instanceof ImagesLoaded ) ) {
51505    return new ImagesLoaded( elem, options, onAlways );
51506  }
51507  // use elem as selector string
51508  var queryElem = elem;
51509  if ( typeof elem == 'string' ) {
51510    queryElem = document.querySelectorAll( elem );
51511  }
51512  // bail if bad element
51513  if ( !queryElem ) {
51514    console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
51515    return;
51516  }
51517
51518  this.elements = makeArray( queryElem );
51519  this.options = extend( {}, this.options );
51520  // shift arguments if no options set
51521  if ( typeof options == 'function' ) {
51522    onAlways = options;
51523  } else {
51524    extend( this.options, options );
51525  }
51526
51527  if ( onAlways ) {
51528    this.on( 'always', onAlways );
51529  }
51530
51531  this.getImages();
51532
51533  if ( $ ) {
51534    // add jQuery Deferred object
51535    this.jqDeferred = new $.Deferred();
51536  }
51537
51538  // HACK check async to allow time to bind listeners
51539  setTimeout( this.check.bind( this ) );
51540}
51541
51542ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
51543
51544ImagesLoaded.prototype.options = {};
51545
51546ImagesLoaded.prototype.getImages = function() {
51547  this.images = [];
51548
51549  // filter & find items if we have an item selector
vendor: 4,347 bytes, lines 51550-51706
51550  this.elements.forEach( this.addElementImages, this );
51551};
51552
51553/**
51554 * @param {Node} element
51555 */
51556ImagesLoaded.prototype.addElementImages = function( elem ) {
51557  // filter siblings
51558  if ( elem.nodeName == 'IMG' ) {
51559    this.addImage( elem );
51560  }
51561  // get background image on element
51562  if ( this.options.background === true ) {
51563    this.addElementBackgroundImages( elem );
51564  }
51565
51566  // find children
51567  // no non-element nodes, #143
51568  var nodeType = elem.nodeType;
51569  if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
51570    return;
51571  }
51572  var childImgs = elem.querySelectorAll('img');
51573  // concat childElems to filterFound array
51574  for ( var i=0; i < childImgs.length; i++ ) {
51575    var img = childImgs[i];
51576    this.addImage( img );
51577  }
51578
51579  // get child background images
51580  if ( typeof this.options.background == 'string' ) {
51581    var children = elem.querySelectorAll( this.options.background );
51582    for ( i=0; i < children.length; i++ ) {
51583      var child = children[i];
51584      this.addElementBackgroundImages( child );
51585    }
51586  }
51587};
51588
51589var elementNodeTypes = {
51590  1: true,
51591  9: true,
51592  11: true
51593};
51594
51595ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
51596  var style = getComputedStyle( elem );
51597  if ( !style ) {
51598    // Firefox returns null if in a hidden iframe https://bugzil.la/548397
51599    return;
51600  }
51601  // get url inside url("...")
51602  var reURL = /url\((['"])?(.*?)\1\)/gi;
51603  var matches = reURL.exec( style.backgroundImage );
51604  while ( matches !== null ) {
51605    var url = matches && matches[2];
51606    if ( url ) {
51607      this.addBackground( url, elem );
51608    }
51609    matches = reURL.exec( style.backgroundImage );
51610  }
51611};
51612
51613/**
51614 * @param {Image} img
51615 */
51616ImagesLoaded.prototype.addImage = function( img ) {
51617  var loadingImage = new LoadingImage( img );
51618  this.images.push( loadingImage );
51619};
51620
51621ImagesLoaded.prototype.addBackground = function( url, elem ) {
51622  var background = new Background( url, elem );
51623  this.images.push( background );
51624};
51625
51626ImagesLoaded.prototype.check = function() {
51627  var _this = this;
51628  this.progressedCount = 0;
51629  this.hasAnyBroken = false;
51630  // complete if no images
51631  if ( !this.images.length ) {
51632    this.complete();
51633    return;
51634  }
51635
51636  function onProgress( image, elem, message ) {
51637    // HACK - Chrome triggers event before object properties have changed. #83
51638    setTimeout( function() {
51639      _this.progress( image, elem, message );
51640    });
51641  }
51642
51643  this.images.forEach( function( loadingImage ) {
51644    loadingImage.once( 'progress', onProgress );
51645    loadingImage.check();
51646  });
51647};
51648
51649ImagesLoaded.prototype.progress = function( image, elem, message ) {
51650  this.progressedCount++;
51651  this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
51652  // progress event
51653  this.emitEvent( 'progress', [ this, image, elem ] );
51654  if ( this.jqDeferred && this.jqDeferred.notify ) {
51655    this.jqDeferred.notify( this, image );
51656  }
51657  // check if completed
51658  if ( this.progressedCount == this.images.length ) {
51659    this.complete();
51660  }
51661
51662  if ( this.options.debug && console ) {
51663    console.log( 'progress: ' + message, image, elem );
51664  }
51665};
51666
51667ImagesLoaded.prototype.complete = function() {
51668  var eventName = this.hasAnyBroken ? 'fail' : 'done';
51669  this.isComplete = true;
51670  this.emitEvent( eventName, [ this ] );
51671  this.emitEvent( 'always', [ this ] );
51672  if ( this.jqDeferred ) {
51673    var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
51674    this.jqDeferred[ jqMethod ]( this );
51675  }
51676};
51677
51678// --------------------------  -------------------------- //
51679
51680function LoadingImage( img ) {
51681  this.img = img;
51682}
51683
51684LoadingImage.prototype = Object.create( EvEmitter.prototype );
51685
51686LoadingImage.prototype.check = function() {
51687  // If complete is true and browser supports natural sizes,
51688  // try to check for image status manually.
51689  var isComplete = this.getIsImageComplete();
51690  if ( isComplete ) {
51691    // report based on naturalWidth
51692    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
51693    return;
51694  }
51695
51696  // If none of the checks above matched, simulate loading on detached element.
51697  this.proxyImage = new Image();
51698  this.proxyImage.addEventListener( 'load', this );
51699  this.proxyImage.addEventListener( 'error', this );
51700  // bind to image as well for Firefox. #191
51701  this.img.addEventListener( 'load', this );
51702  this.img.addEventListener( 'error', this );
51703  this.proxyImage.src = this.img.src;
51704};
51705
51706LoadingImage.prototype.getIsImageComplete = function() {
51707  // check for non-zero, non-undefined naturalWidth
51708  // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
51709  return this.img.complete && this.img.naturalWidth;
51710};
51711
51712LoadingImage.prototype.confirm = function( isLoaded, message ) {
51713  this.isLoaded = isLoaded;
51714  this.emitEvent( 'progress', [ this, this.img, message ] );
51715};
51716
51717// ----- events ----- //
51718
51719// trigger specified handler for event type
51720LoadingImage.prototype.handleEvent = function( event ) {
51721  var method = 'on' + event.type;
51722  if ( this[ method ] ) {
51723    this[ method ]( event );
51724  }
51725};
51726
51727LoadingImage.prototype.onload = function() {
51728  this.confirm( true, 'onload' );
51729  this.unbindEvents();
51730};
51731
51732LoadingImage.prototype.onerror = function() {
51733  this.confirm( false, 'onerror' );
51734  this.unbindEvents();
51735};
51736
51737LoadingImage.prototype.unbindEvents = function() {
51738  this.proxyImage.removeEventListener( 'load', this );
51739  this.proxyImage.removeEventListener( 'error', this );
51740  this.img.removeEventListener( 'load', this );
51741  this.img.removeEventListener( 'error', this );
51742};
51743
51744// -------------------------- Background -------------------------- //
51745
51746function Background( url, element ) {
51747  this.url = url;
51748  this.element = element;
51749  this.img = new Image();
51750}
51751
51752// inherit LoadingImage prototype
51753Background.prototype = Object.create( LoadingImage.prototype );
51754
51755Background.prototype.check = function() {
51756  this.img.addEventListener( 'load', this );
51757  this.img.addEventListener( 'error', this );
51758  this.img.src = this.url;
51759  // check if image is already complete
51760  var isComplete = this.getIsImageComplete();
51761  if ( isComplete ) {
51762    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
51763    this.unbindEvents();
51764  }
51765};
51766
51767Background.prototype.unbindEvents = function() {
51768  this.img.removeEventListener( 'load', this );
51769  this.img.removeEventListener( 'error', this );
51770};
51771
51772Background.prototype.confirm = function( isLoaded, message ) {
51773  this.isLoaded = isLoaded;
51774  this.emitEvent( 'progress', [ this, this.element, message ] );
51775};
51776
51777// -------------------------- jQuery -------------------------- //
51778
51779ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
51780  jQuery = jQuery || window.jQuery;
51781  if ( !jQuery ) {
51782    return;
51783  }
51784  // set local variable
51785  $ = jQuery;
51786  // $().imagesLoaded()
51787  $.fn.imagesLoaded = function( options, callback ) {
51788    var instance = new ImagesLoaded( this, options, callback );
51789    return instance.jqDeferred.promise( $(this) );
51790  };
51791};
51792// try making plugin
51793ImagesLoaded.makeJQueryPlugin();
51794
51795// --------------------------  -------------------------- //
51796
51797return ImagesLoaded;
51798
51799});
51800
51801
51802/***/ }),
51803/* 252 */
51804/***/ (function(module, __webpack_exports__, __webpack_require__) {
51805
51806"use strict";
51807/* WEBPACK VAR INJECTION */(function($) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_swiper_bundle__ = __webpack_require__(6);
51808/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_blockui__ = __webpack_require__(147);
51809/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_blockui___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_blockui__);
51810/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_select2__ = __webpack_require__(149);
51811/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_select2___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_select2__);
51812/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_masonry_layout__ = __webpack_require__(7);
51813/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_masonry_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_masonry_layout__);
51814
51815
51816
51817
51818
51819/* harmony default export */ __webpack_exports__["a"] = ({
51820    init: function init() {
51821
51822    },
51823    finalize: function finalize() {
51824
51825      /**
51826       * Grid Task
51827       * @Masonry
51828       */
51829        if ( $('.taskMasonry').length ) {
51830            $('.taskMasonry').each(function (index) {
51831
51832                var $elem = 'masonry-task-' + index;
51833
51834                $(this).addClass($elem);
51835
51836                var $masonry = '.' + $elem;
51837
51838                var $grid = {};
51839
51840                $grid[index] = new __WEBPACK_IMPORTED_MODULE_3_masonry_layout___default.a($masonry, {
51841                    percentPosition   :   true,
51842                    itemSelector      :   '.taskMasonry-item',
51843                    gutter            :   0,
51844                    transitionDuration:   0,
51845                    columnWidth       :   '.grid-sizer',
51846                });
51847
51848                $(window).on('load resize', function () {
51849                    $grid[index].reloadItems();
51850                    $grid[index].layout();
51851                });
51852
51853            });
51854        }
51855
51856      /**
51857       * News & Events
51858       * @Masonry
51859       */
51860        if ( $('.newseventsMasonry').length ) {
51861            $('.newseventsMasonry').each(function (index) {
51862
51863                var $elem = 'masonry-newsevents-' + index;
51864
51865                $(this).addClass($elem);
51866
51867                var $masonry = '.' + $elem;
51868
51869                var $grid = {};
51870
51871                $grid[index] = new __WEBPACK_IMPORTED_MODULE_3_masonry_layout___default.a($masonry, {
51872                    percentPosition   :   true,
51873                    itemSelector      :   '.newseventsMasonry-item',
51874                    gutter            :   0,
51875                    transitionDuration:   0,
51876                    columnWidth       :   '.grid-sizer',
51877                });
51878
51879                $(window).on('load resize', function () {
51880                    $grid[index].reloadItems();
51881                    $grid[index].layout();
51882                });
51883
51884            });
51885        }
51886
51887      /**
51888       * GlobalElements
51889       * @type {{init: init}}
51890       */
51891        var GlobalElements = function () {
51892
51893
51894
51895          /**
51896           * Accordion
51897           * @param data
51898           * @constructor
51899           */
51900            var Accordion = function () {
51901
51902              /**
51903               * Accordion
51904               * @click
51905               */
51906                $(document).on('click', '.accordion-title', function (e) {
51907
51908                    var $li = $(this).parent();
51909
51910                    if ( $li.hasClass('active') ) {
51911                        $('.accordion').find('.active').removeClass('active');
51912                    } else {
51913                        $('.accordion').find('.active').removeClass('active');
51914                        $li.addClass('active');
51915                    }
51916
51917                    e.preventDefault();
51918
51919                });
51920
51921            }
51922
51923
51924
51925          /**
51926           * Downloads
51927           * @constructor
51928           */
51929            var Downloads = function () {
51930
51931
51932
51933            }
51934
51935          /**
51936           * FloatingBanner
51937           * @constructor
51938           */
51939            var FloatingBanner = function () {
51940
51941                $(window).on('scroll', function () {
51942
51943                    var windowPosition = $(window).scrollTop(),
51944                    topPanel = 115,
51945                    window_width = $(window).width();
51946
51947                    if ( window_width < 1200 ) {
51948                        topPanel = 0;
51949                    }
51950
51951                    if (windowPosition >
51951 topPanel && windowPosition < 810) {
51952                        $('.floating_section').addClass('scroll');
51953                    } else {
51954                        $('.floating_section').removeClass('scroll');
51955                    }
51956
51957                }).scroll();
51958
51959            }
51960
51961          /**
51962           * Sticky
51963           * @constructor
51964           */
51965            var Sticky = function () {
51966
51967                $(document).on('click', '.dynamic__navsections ul > li > a', function (e) {
51968
51969                    var elem = $(this).attr('href'),
51970                    top = $(elem).offset().top;
51971
51972                    $('body,html').animate({scrollTop: top}, 400);
51973
51974                    $('.dynamic__navsections ul').find('li.active').removeClass('active');
51975                    $(this).parent().addClass('active');
51976
51977                    e.preventDefault();
51978
51979                });
51980
51981            }
51982
51983            var DynamicSlider = function () {
51984                if ($('.dynamic__slider').length > 0) {
51985                    new __WEBPACK_IMPORTED_MODULE_0_swiper_bundle__["a" /* default */]('.dynamic__slider .swiper-container', {
51986                        autoHeight: true, //enable auto height
51987                        slidesPerView : 1,
51988                        spaceBetween  : 0,
51989                        loop          : true,
51990                        effect          :'fade',
51991                        speed           : 800,
51992                        pagination: {
51993                            el          : '.dynamic__slider .swiper-pagination',
51994                            clickable   : true,
51995                            type        : 'bullets',
51996                        },
51997                        navigation: {
51998                            nextEl      : '.dynamic__slider .swiper-button-next',
51999                            prevEl      : '.dynamic__slider .swiper-button-prev',
52000                        },
52001                    });
52002                }
52003            };
52004
52005            var Pardotform = function(){
52006              document.getElementsByClassName('pardotForm').each(function(item) {
52007                var source = getCookie('utm_source');
52008                var campaign = getCookie('utm_campaign');
52009                var medium = getCookie('utm_medium');
52010                var src = item.getAttribute('src2');
52011                item.setAttribute('src',src+source+campaign+medium);
52012              });
52013              function getCookie(name) {
52014                name = name + '=';
52015                var decodedCookie = decodeURIComponent(document.cookie);
52016                var ca = decodedCookie.split(';');
52017                for(var i = 0; i <ca.length; i++) {
52018                  var c = ca[i];
52019                  while (c.charAt(0) == ' ') {
52020                    c = c.substring(1);
52021                  }
52022                  if (c.indexOf(name) == 0) {
52023                    return 'utm_'+name+'='+c.substring(name.length, c.length);
52024                  }
52025                }
52026
52027                return '';
52028              }
52029        }
52030          /**
52031           * @return
52032           */
52033            return {
52034                init: function () {
52035                    Accordion();
52036                    Downloads();
52037                    FloatingBanner();
52038                    Sticky();
52039                    DynamicSlider();
52040                    Pardotform();
52041                },
52042            };
52043        }();
52044
52045      /**
52046       * Init GlobalElements
52047       */
52048        GlobalElements.init();
52049
52050      /**
52051       * Select2
52052       * Normal
52053       */
52054        if ( $('.js-select').length ) {
52055            $('.js-select').select2({
52056                minimumResultsForSearch :   Infinity,
52057                containerCssClass       :   'select2-lg',
52058            });
52059
52060            $('.js-select-md').select2({
52061                minimumResultsForSearch :   Infinity,
52062                containerCssClass       :   'select2-md',
52063            });
52064
52065            $('.js-select-sm').select2({
52066                minimumResultsForSearch :   Infinity,
52067                containerCssClass       :   'select2-sm',
52068            });
52069        }
52070
52071      /**
52072       * Masonry News and Event
52073       */
52074        if ($('.newsevent-masonry').length) {
52075            var $grid = new __WEBPACK_IMPORTED_MODULE_3_masonry_layout___default.a('.newsevent-masonry', {
52076                percentPosition   :   true,
52077                itemSelector      :   '.item',
52078                gutter            :   0,
52079                transitionDuration:   0,
52080                columnWidth       :   '.grid-sizer',
52081            });
52082            $grid.reloadItems();
52083            $grid.layout();
52084
52085            setTimeout(function () {
52086
52087                $grid.reloadItems();
52088                $grid.layout();
52089
52090            }, 100);
52091
52092            $(window).on('resize', function () {
52093                $grid.reloadItems();
52094                $grid.layout();
52095            });
52096        }
52097
52098      /**
52099       * Play Button Video
52100       */
52101        if ($('.video-player').length) {
52102
52103          /**
52104           * Insert Button
52105           */
52106            $('.video-player').each(function () {
52107
52108                $(this).append($('<a href="#play" class="btn-video-play"></a>'));
52109
52110            });
52111
52112          /**
52113           * Click Button Play
52114           */
52115            $(document).on('click', '.btn-video-play', function () {
52116
52117                var video = $(this).parent().find('video');
52118
52119                if (video.get(0).paused) {
52120                    video.get(0).play();
52121                    $(this).fadeOut();
52122                } else {
52123                    video.get(0).pause();
52124                    $(this).fadeIn();
52125                }
52126
52127            });
52128        }
52129
52130      /********************************************************************
52131       * Filter Ajax Component
52132       * News and Events
52133       * @type {{init: init}}
52134       */
52135        var FilterNewsEventAjax = function () {
52136
52137          /**
52138           * const
52139           * @type {{overlayCSS: {background: string, opacity: number}, message: string}}
52140           */
52141            var loader = {message : '', overlayCSS : {background : '#fff', opacity : 0.6}};
52142
52143          /**
52144           * Ajax
52145           * @param container
52146           * @param data
52147           * @constructor
52148           */
52149            var Ajax = function (data) {
52150                if ( data === void 0 ) data = '';
52151
52152
52153              /**
52154               *
52155               * @type {jQuery|HTMLElement}
52156               */
52157                var $container_result   = $('.filterNewsEvent .resultAjax'),                  //Container
52158                $container_items    = $container_result.find('.recfilter_section__list'), //Container Items
52159                $month_panel        = $('.filterNewsEventFormMonth'),                     //Panel Month
52160                $form               = $('.filterNewsEventForm');                          //Form
52161
52162              /**
52163               * Data
52164               * @type {string}
52165               */
52166                data += $form.serialize() + '&month=' + $('.filterNewsEventFormDate').val();
52167
52168                $.ajax({
52169                    beforeSend  :   function () {
52170                        $container_result.block(loader);
52171                    },
52172                    data        :   data,
52173                    dataType    :   'json',
52174                    method      :   'POST',
52175                    complete    :   function () {
52176                        $container_result.unblock();
52177                    },
52178                    success     :   function ( data ) {
52179
52180                        if ( data.success === false ) {
52181                            $('.newsevent-masonry').addClass('recfilter_section__list-empty');
52182                        } else {
52183                            $('.newsevent-masonry').removeClass('recfilter_section__list-empty');
52184                        }
52185
52186                        /**
52187                         * Items
52188                         */
52189
52190                        /**
52191                         * Html
52192                         */
52193                        $container_items.html(data.data.html).ready(function () {
52194
52195                            var grid = new __WEBPACK_IMPORTED_MODULE_3_masonry_layout___default.a('.newsevent-masonry');
52196                            grid.reloadItems();
52197                            setTimeout(function () {
52198                                grid = new __WEBPACK_IMPORTED_MODULE_3_masonry_layout___default.a('.newsevent-masonry', {
52199                                    percentPosition   :   true,
52200                                    itemSelector      :   '.item',
52201                                    isInitLayout      :   true,
52202                                    gutter            :   0,
52203                                    transitionDuration:   0,
52204                                    columnWidth       :   '.grid-sizer',
52205                                });
52206                            }, 200)
52207
52208                        });
52209
52210                        /**
52211                         * Masonry
52212                         */
52213                        $(window).trigger('resize');
52214
52215                        /**
52216                         * Month Panel
52217                         */
52218                        $month_panel.html(data.data.month);
52219
52220                    },
52221                    url         :   window.nec.ajax_url,
52222                });
52223            }
52224
52225          /**
52226           * News and Event
52227           * @constructor
52228           */
52229            var NewsEvent = function () {
52230
52231              /**
52232               * Select
52233               * @change
52234               */
52235                $(document).on('change', '.filterNewsEvent select', function () {
52236
52237                    Ajax();
52238
52239                });
52240
52241              /**
52242               * Next or Prev Month
52243               * @click
52244               */
52245                $(document).on('click', '.filterNewsEventMonth', function () {
52246
52247                    var month = $(this).data('month');
52248
52249                    $('.filterNewsEventFormDate').val(month);
52250
52251                    Ajax('month_custom=' + month + '&');
52252
52253                });
52254
52255            }
52256
52257          /**
52258           * @return
52259           */
52260            return {
52261                init: function () {
52262                    NewsEvent();
52263                },
52264            };
52265        }();
52266
52267      /**
52268       * Init Filter Ajax
52269       */
52270        FilterNewsEventAjax.init();
52271
52272      /**
52273       * Filter Ajax Component
52274       * Taxonomy
52275       * @type {{init: init}}
52276       */
52277        var FilterTaxonomyAjax = function () {
52278
52279          /**
52280           * const
52281           * @type {{overlayCSS: {background: string, opacity: number}, message: string}}
52282           */
52283            var loader = {message : '', overlayCSS : {background : '#fff', opacity : 0.6}};
52284
52285          /**
52286           * Ajax
52287           * @param container
52288           * @param data
52289           * @constructor
52290           */
52291            var Ajax = function (data, type) {
52292                if ( data === void 0 ) data = '';
52293                if ( type === void 0 ) type = 'post';
52294
52295
52296              /**
52297               *
52298               * @type {jQuery|HTMLElement}
52299               */
52300                var $container          = $('.resultTaxonomyAjax'),
52301                $container_result   = $('.resultTaxonomyAjaxPost'),
52302                $form               = $('.filterTaxonomy');
52303
52304                if ( $form.length ) {
52305
52306                  /**
52307                   * Data
52308                   * @type {string}
52309                   */
52310                    data += $form.serialize() + '&level=' + $('[name=select_level]').val() + '&place=' + $('[name=select_place]').val() + '&' + '&type=' + type;
52311
52312                    $.ajax({
52313                        beforeSend: function () {
52314
52315                            if (type == 'post') {
52316                                $container.block(loader);
52317                            }
52318
52319                        },
52320                        data: data,
52321                        dataType: 'json',
52322                        method: 'POST',
52323                        complete: function () {
52324
52325                            if (type == 'post') {
52326                                $container.unblock();
52327                            } else {
52328                                $('.taxfilter_section__filter-list--input').removeClass('active');
52329                            }
52330
52331                        },
52332                        success: function (data) {
52333
52334                          /**
52335                           * Search
52336                           */
52337                            if (type == 'search') {
52338                                $('.filterTaxonomySearchResultTax').html(data.data.html);
52339
52340                                return false;
52341                            }
52342
52343                          /**
52344                           * Check Badges
52345                           */
52346                            checkSelectedBadges();
52347
52348                          /**
52349                           * Html
52350                           */
52351                            $container_result.html(data.data.html).ready(function () {
52352                            });
52353
52354
52355                        },
52356                        url: window.nec.ajax_url,
52357                    });
52358                }
52359            }
52360
52361          /**
52362           * Select Multiple
52363           * @constructor
52364           */
52365            var Select = function () {
52366
52367              /**
52368               *
52369               */
52370                $.fn.select2.amd.require(
52371                    [
52372                    'select2/selection/single',
52373                    'select2/selection/placeholder',
52374                    'select2/dropdown',
52375                    'select2/dropdown/attachBody',
52376                    'select2/utils' ],
52377                    function (SingleSelection, Placeholder, Dropdown, AttachBody, Utils) {
52378
52379                        var SelectionAdapter = Utils.Decorate(
52380                            SingleSelection,
52381                            Placeholder
52382                        );
52383
52384
52385                        $('.js-select-checkbox').each(function () {
52386                            var $select     = $(this),
52387                            placeholder = $(this).data('placeholder');
52388
52389                            $select.select2({
52390                                placeholder       :   placeholder,
52391                                selectionAdapter  :   SelectionAdapter,
52392                                closeOnSelect     :   false,
52393                                dropdownParent    :   $select.parent(),
52394                                templateResult    :   function (data) {
52395                                console.log(data);
52396                                    if (!data.id) {
52397                                        return data.text; }
52398
52399                                    var $res = $('<div></div>');
52400
52401
52402                                    $res.text(data.text);
52403                                    $res.addClass('wrap');
52404
52405                                    $res.attr('data-name', data.text.trim());
52406                                    $res.attr('data-id', data.id.trim());
52407
52408                                    return $res;
52409                                },
52410                                templateSelection: function (data) {
52411
52412                                    if (!data.id) {
52413                                        return data.text;
52414                                    }
52415
52416                                    var selected  = ($select.val() || []).length;
52417                                    var total     = $('option', $select).length;
52418
52419                                    return placeholder + ' (' + selected + ' of ' + total + ')';
52420
52421                                },
52422                            })
52423
52424                        });
52425
52426                    }
52427                );
52428
52429              /**
52430               * Add Badges
52431               * @click
52432               */
52433            $(document).on('click', '.select2-results__option', function () {
52434
52435                var id    = $(this).find('.wrap').data('id'),
52436                  name  = $(this).find('.wrap').data('name');
52437                var showRow = function(filterObject, rowData, id){
52438                  var show = true;
52439                  Object.entries(filterObject).forEach(function (ref) {
52440                    var key = ref[0];
52441
52442                    show = false;
52443                    var rowArray = rowData.dataset[id].toUpperCase().replace(/\s/g, '').split(',');
52444                    rowArray.forEach(function (element) {
52445                      if (filterObject[key].hasOwnProperty(element)) {
52446                        show = true;
52447                      }
52448                    });
52449                    if(!show){ return false }
52450                  })
52451                  return show;
52452                }
52453                if ($('.faculty_section').length) {
52454                  var filterObject = {};
52455                  $('.select2-results__option--selected').each(function (i, el) {
52456                    var filter = $(this).closest('.col').find('select')[0].dataset.placeholder.toLowerCase();
52457                    var option = el.innerText.toUpperCase().replace(/\s/g, '');
52458                    filterObject.hasOwnProperty(filter) ? '':filterObject[filter]={};
52459                    filterObject[filter][option] = 1;
52460                  });
52461                  var row = $('table').find('tr:not(.header)');
52462                  if ( !$(this).hasClass('select2-results__option--selected') ) {
52463                    row.each(function (i, rowData) {
52464                      var show = showRow(filterObject, rowData, id);
52465                      show ? $(rowData).show().addClass('active') : $(rowData).hide().removeClass('active');
52466                    });
52467                  }
52468                  else {
52469                    row = $('table').find('tr:not(.header)');
52470                    row.each(function (i, rowData) {
52471                      var show = showRow(filterObject, rowData, id);
52472                      if (show === true) {
52473                        $(rowData).show().addClass('active')
52474                      }
52475                      else {
52476                        $(rowData).hide().removeClass('active');
52477                      }
52478                    });
52479                  }
52480                }
52481                else {
52482                  var url = window.location.origin + window.location.pathname;
52483                  var params = new URLSearchParams(window.location.search);
52484                  var filter = $(this.closest('.col')).find('select')[0].getAttribute('name');
52485                  var param = 'category[]';
52486                  if (filter === 'select_place') {
52487                    param = 'location[]';
52488                  } else if (filter === 'select_level') {
52489                    param = 'level[]';
52490                  }
52491                  if (!$(this).hasClass('select2-results__option--selected')) {
52492                    $('.filterTaxonomyBadges').find('[data-id="' + id + '"]').remove();
52493                    var filteredParams = params.getAll(param)
52494                      .filter(function (el) {
52495                        return el !== name.trim();
52496                      }).map(function (el) {
52497                        return [param, el];
52498                      });
52499                    params.delete(param);
52500                    filteredParams.map(function (el) {
52501                      params.append(param,el);
52502                    })
52503                  } else {
52504                    $('.filterTaxonomyBadges').append(
52505                      '<li data-type="sellect" data-id="' + id + '" data-name="' + name.trim() + '">' +
52506                      '<a href="#remove-' + id + '">' + name.trim() + '</a>' +
52507                      '</li>'
52508                    );
52509                    params.append(param, name.trim())
52510                  }
52511                  window.history.replaceState(null, null, url+'?'+params.toString()); // or pushState
52512
52513
52514
52515
52516                  /**
52517                   * Return Ajax
52518                   */
52519                  Ajax();
52520                }
52521              });
52522
52523                Ajax();
52524
52525            }
52526
52527          /**
52528           * Search Input
52529           * @constructor
52530           */
52531            var Search = function () {
52532
52533              /**
52534               * @click
52535               */
52536                $(document).on('click', '.filterTaxonomySearchResultCat', function (e) {
52537                    e.preventDefault();
52538                    console.log('--2')
52539
52540                  /**
52541                   * const
52542                   * @type {jQuery|HTMLElement}
52543                   */
52544                    var $this       =   $(this),
52545                    id          =   $this.data('id'),
52546                    name        =   $this.text().trim(),
52547                    $inp_cat    =   $('.filterTaxonomy input[name=category]'),
52548                    def_value   =   $inp_cat.val();
52549
52550                  /**
52551                   *
52552                   */
52553                  var url = window.location.origin + window.location.pathname;
52554                  var params = new URLSearchParams(window.location.search);
52555                    var param = 'category[]';
52556                    if ( $('.filterTaxonomyPanel [data-id=' + id + ']').length ) {
52557                        $inp_cat.val(function (index, value) {
52558                            return value.replace(id + ',', '');
52559                        });
52560
52561                        $('.filterTaxonomyPanel [data-id=' + id + ']').remove();
52562                    } else {
52563                        $('.filterTaxonomyBadges').append(
52564                            '<li data-type="category" data-id="'+id+'" data-name="'+name+'">' +
52565                            '<a href="#remove-'+id+'">'+name+'</a>' +
52566                            '</li>'
52567                        );
52568                        params.append(param, name.trim());
52569                        $inp_cat.val(def_value + id + ',');
52570                    }
52571                    console.log('param');
52572                  window.history.replaceState(null, null, url+'?'+params.toString()); // or pushState
52573                  /**
52574                   * Return Ajax
52575                   */
52576                    Ajax();
52577
52578                  /**
52579                   * Check Badges
52580                   */
52581                    checkSelectedBadges();
52582
52583                });
52584
52585              /**
52586               * @focus
52587               */
52588                $(document).on('focus', '.filterTaxonomySearch', function () {
52589
52590                    $('.filterTaxonomySearchResult').addClass('open');
52591
52592                });
52593
52594              /**
52595               * @focusout
52596               */
52597                $(document).on('focusout', '.filterTaxonomySearch', function () {
52598
52599                });
52600
52601              /**
52602               * @keyup
52603               */
52604                $(document).on('keyup', '.filterTaxonomySearch', function () {
52605                    var $this = $(this),
52606                    value = $this.val();
52607
52608                    if ( value.length ) {
52609                        $this.parent().addClass('active');
52610                        $('.filterTaxonomySearchResultDefault').hide();
52611                        $('.filterTaxonomySearchResultTax').show();
52612                    } else {
52613                        $this.parent().removeClass('active');
52614                        $('.filterTaxonomySearchResultDefault').show();
52615                        $('.filterTaxonomySearchResultTax').hide();
52616                    }
52617
52618                  /**
52619                   * Return Ajax
52620                   */
52621                    Ajax('', 'search');
52622
52623                });
52624
52625              /**
52626               * Search Section Group
52627               * @mouseup
52628               */
52629                $(document).mouseup(function (e) {
52630
52631                    var div = $('.filterTaxonomySearchGroup');
52632
52633                    if (!div.is(e.target)
52634                    && div.has(e.target).length === 0) {
52635                        $('.filterTaxonomySearchResultDefault').show();
52636                        $('.filterTaxonomySearchResultTax').html('');
52637                        $('.filterTaxonomySearchResult').removeClass('open');
52638                        $('.filterTaxonomySearch').val('');
52639                    }
52640
52641                });
52642
52643            }
52644
52645          /**
52646           * Panel
52647           * @constructor
52648           */
52649            var Panel = function () {
52650
52651              /**
52652               * Remove Badges
52653               * @click
52654               */
52655              $(document).on('click', '.filterTaxonomyBadges a', function (e) {
52656
52657                var $elem   =   $(this).parent(),
52658                  id      =   $elem.data('id'),
52659                  type    =   $elem.data('type');
52660                var name = $elem.data('name')
52661                var url = window.location.origin + window.location.pathname;
52662                var params = new URLSearchParams(window.location.search);
52663                var selectBox = $('.js-select-checkbox option[value="' + id + '"]');
52664                if (type !== 'category') {
52665                  var filter = $(selectBox.closest('.col')).find('select')[0].getAttribute('name');
52666                }
52667                var param = 'category[]';
52668                if (filter === 'select_place') {
52669                  param = 'location[]';
52670                } else if (filter === 'select_level') {
52671                  param = 'level[]';
52672                }
52673                var filteredParams = params.getAll(param)
52674                  .filter(function (el) {
52675                    return el !== name.trim();
52676                  }).map(function (el) {
52677                    return [param, el];
52678                  });
52679                params.delete(param);
52680                filteredParams.map(function (el) {
52681                  params.append(param,el);
52682                });
52683                window.history.replaceState(null, null, url+'?'+params.toString()); // or pushState
52684
52685                $('.js-select-checkbox option[value="' + id + '"]').prop('selected', false);
52686                $('.js-select-checkbox').trigger('change');
52687
52688                $(this).parent().remove();
52689
52690                /**
52691                 * Replace Category
52692                 */
52693                if ( type === 'category' ) {
52694                  $('.filterTaxonomy input[name=category]').val(function (index, value) {
52695                    return value.replace(id + ',', '');
52696                  });
52697                }
52698
52699                /**
52700                 * Return Ajax
52701                 */
52702                Ajax();
52703
52704                /**
52705                 * preventDefault
52706                 */
52707                e.preventDefault();
52708
52709              });
52710
52711              /**
52712               * Clear All Filters
52713               * @click
52714               */
52715                $(document).on('click', '.filterTaxonomyClear', function () {
52716
52717                  /**
52718                   *
52719                   */
52720                    $('.js-select-checkbox').val(null).trigger('change');
52721                    $('.filterTaxonomyBadges').html('');
52722
52723                  /**
52724                   * Check Badges
52725                   */
52726                    checkSelectedBadges();
52727
52728                });
52729
52730              /**
52731               * View List
52732               * @click
52733               */
52734                $(document).on('click', '.filterTaxonomyView', function () {
52735
52736                    $(this).toggleClass('grid');
52737
52738                    $('.resultTaxonomyAjaxList').toggleClass('table');
52739
52740                });
52741
52742            };
52743
52744          /**
52745           * Check Badges
52746           */
52747            var checkSelectedBadges = function () {
52748                var $container    = $('.filterTaxonomyPanel'),
52749                $elem         = $container.find('li');
52750
52751                if ( $elem.length ) {
52752                    $container.removeClass('hidden');
52753
52754                    $('.resultTaxonomyAjaxCat').hide();
52755                    $('.resultTaxonomyAjaxPost').show();
52756                } else {
52757                    $container.addClass('hidden');
52758
52759                    $('.resultTaxonomyAjaxCat').show();
52760                    $('.resultTaxonomyAjaxPost').html('').hide();
52761                }
52762            };
52763
52764          /**
52765           * Mobile
52766           * @constructor
52767           */
52768            var Mobile = function () {
52769
52770              /**
52771               * Mobile Filter Open
52772               * @click
52773               */
52774                $(document).on('click', '.filterTaxonomyMobileBtn', function (e) {
52775
52776                    $('body').toggleClass('no-scroll');
52777                    $('.filterTaxonomyMobilePopup').toggleClass('active');
52778
52779                    e.preventDefault();
52780                });
52781
52782
52783            }
52784
52785          /**
52786           * @return
52787           */
52788            return {
52789                init: function () {
52790                    Select();
52791                    Search();
52792                    Panel();
52793                    Mobile();
52794                },
52795            };
52796        }();
52797      /**
52798       * Init Filter Ajax
52799       */
52800        FilterTaxonomyAjax.init();
52801
52802    },
52803});
52804
52805/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(2)))
52806
52807/***/ }),
52808/* 253 */
52809/***/ (function(module, __webpack_exports__, __webpack_require__) {
52810
52811"use strict";
52812/* WEBPACK VAR INJECTION */(function($) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_swiper_bundle__ = __webpack_require__(6);
52813/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_blockui__ = __webpack_require__(147);
52814/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_blockui___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_blockui__);
52815/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_select2__ = __webpack_require__(149);
52816/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_select2___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_select2__);
52817/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_masonry_layout__ = __webpack_require__(7);
52818/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_masonry_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_masonry_layout__);
52819
52820
52821
52822
52823
52824/* harmony default export */ __webpack_exports__["a"] = ({
52825  init: function init() {},
52826  finalize: function finalize() {
52827    /**
52828     * Grid Task
52829     * @Masonry
52830     */
52831    if ($('.taskMasonry').length) {
52832      $('.taskMasonry').each(function (index) {
52833        var $elem = 'masonry-task-' + index;
52834
52835        $(this).addClass($elem);
52836
52837        var $masonry = '.' + $elem;
52838
52839        var $grid = {};
52840
52841        $grid[index] = new __WEBPACK_IMPORTED_MODULE_3_masonry_layout___default.a($masonry, {
52842          percentPosition: true,
52843          itemSelector: '.taskMasonry-item',
52844          gutter: 0,
52845          transitionDuration: 0,
52846          columnWidth: '.grid-sizer',
52847        });
52848
52849        $(window).on('load resize', function () {
52850          $grid[index].reloadItems();
52851          $grid[index].layout();
52852        });
52853      });
52854    }
52855
52856    /**
52857     * News & Events
52858     * @Masonry
52859     */
52860    if ($('.newseventsMasonry').length) {
52861      $('.newseventsMasonry').each(function (index) {
52862        var $elem = 'masonry-newsevents-' + index;
52863
52864        $(this).addClass($elem);
52865
52866        var $masonry = '.' + $elem;
52867
52868        var $grid = {};
52869
52870        $grid[index] = new __WEBPACK_IMPORTED_MODULE_3_masonry_layout___default.a($masonry, {
52871          percentPosition: true,
52872          itemSelector: '.newseventsMasonry-item',
52873          gutter: 0,
52874          transitionDuration: 0,
52875          columnWidth: '.grid-sizer',
52876        });
52877
52878        $(window).on('load resize', function () {
52879          $grid[index].reloadItems();
52880          $grid[index].layout();
52881        });
52882      });
52883    }
52884
52885    /**
52886     * GlobalElements
52887     * @type {{init: init}}
52888     */
52889    var GlobalElements = (function () {
52890      /**
52891       * Accordion
52892       * @param data
52893       * @constructor
52894       */
52895      var Accordion = function () {
52896        /**
52897         * Accordion
52898         * @click
52899         */
52900        $(document).on('click', '.accordion-title', function (e) {
52901          var $li = $(this).parent();
52902
52903          if ($li.hasClass('active')) {
52904            $('.accordion').find('.active').removeClass('active');
52905          } else {
52906            $('.accordion').find('.active').removeClass('active');
52907            $li.addClass('active');
52908          }
52909
52910          e.preventDefault();
52911        });
52912      };
52913
52914      /**
52915       * Downloads
52916       * @constructor
52917       */
52918      var Downloads = function () {};
52919
52920      /**
52921       * FloatingBanner
52922       * @constructor
52923       */
52924      var FloatingBanner = function () {
52925        $(window)
52926          .on('scroll', function () {
52927            var windowPosition = $(window).scrollTop(),
52928              topPanel = 115,
52929              window_width = $(window).width();
52930
52931            if (window_width < 1200) {
52932              topPanel = 0;
52933            }
52934
52935            if (windowPosition > topPanel && windowPosition < 810) {
52936              $('.floating_section').addClass('scroll');
52937            } else {
52938              $('.floating_section').removeClass('scroll');
52939            }
52940          })
52941          .scroll();
52942      };
52943
52944      /**
52945       * Sticky
52946       * @constructor
52947       */
52948      var Sticky = function () {
52949        $(document).on(
52950          'click',
52951          '.dynamic__navsections ul > li > a',
52952          function (e) {
52953            var elem = $(this).attr('href'),
52954              top = $(elem).offset().top;
52955
52956            $('body,html').animate({ scrollTop: top }, 400);
52957
52958            $('.dynamic__navsections ul')
52959              .find('li.active')
52960              .removeClass('active');
52961            $(this).parent().addClass('active');
52962
52963            e.preventDefault();
52964          }
52965        );
52966      };
52967
52968      var DynamicSlider = function () {
52969        if ($('.dynamic__slider').length > 0) {
52970          new __WEBPACK_IMPORTED_MODULE_0_swiper_bundle__["a" /* default */]('.dynamic__slider .swiper-container', {
52971            autoHeight: true, //enable auto height
52972            slidesPerView: 1,
52973            spaceBetween: 0,
52974            loop: true,
52975            effect: 'fade',
52976            speed: 800,
52977            pagination: {
52978              el: '.dynamic__slider .swiper-pagination',
52979              clickable: true,
52980              type: 'bullets',
52981            },
52982            navigation: {
52983              nextEl: '.dynamic__slider .swiper-button-next',
52984              prevEl: '.dynamic__slider .swiper-button-prev',
52985            },
52986          });
52987        }
52988      };
52989      var Pardotform = function () {
52990        var elements = document.getElementsByClassName('pardotForm');
52991
52992        if (elements.length) {
52993          elements.each(function (item) {
52994            var source = getCookie('utm_source');
52995            var campaign = getCookie('utm_campaign');
52996            var medium = getCookie('utm_medium');
52997            var src = item.getAttribute('src2');
52998            item.setAttribute('src', src + source + campaign + medium);
52999          });
53000        }
53001
53002        function getCookie(name) {
53003          name = name + '=';
53004          var decodedCookie = decodeURIComponent(document.cookie);
53005          var ca = decodedCookie.split(';');
53006          for (var i = 0; i < ca.length; i++) {
53007            var c = ca[i];
53008            while (c.charAt(0) == ' ') {
53009              c = c.substring(1);
53010            }
53011            if (c.indexOf(name) == 0) {
53012              return 'utm_' + name + '=' + c.substring(name.length, c.length);
53013            }
53014          }
53015
53016          return '';
53017        }
53018      };
53019      /**
53020       * @return
53021       */
53022      return {
53023        init: function () {
53024          Accordion();
53025          Downloads();
53026          FloatingBanner();
53027          Sticky();
53028          DynamicSlider();
53029          Pardotform();
53030        },
53031      };
53032    })();
53033
53034    /**
53035     * Init GlobalElements
53036     */
53037    GlobalElements.init();
53038
53039    /**
53040     * Select2
53041     * Normal
53042     */
53043    if ($('.js-select').length) {
53044      $('.js-select').select2({
53045        minimumResultsForSearch: Infinity,
53046        containerCssClass: 'select2-lg',
53047      });
53048
53049      $('.js-select-md').select2({
53050        minimumResultsForSearch: Infinity,
53051        containerCssClass: 'select2-md',
53052      });
53053
53054      $('.js-select-sm').select2({
53055        minimumResultsForSearch: Infinity,
53056        containerCssClass: 'select2-sm',
53057      });
53058    }
53059
53060    /**
53061     * Masonry News and Event
53062     */
53063    if ($('.newsevent-masonry').length) {
53064      var $grid = new __WEBPACK_IMPORTED_MODULE_3_masonry_layout___default.a('.newsevent-masonry', {
53065        percentPosition: true,
53066        itemSelector: '.item',
53067        gutter: 0,
53068        transitionDuration: 0,
53069        columnWidth: '.grid-sizer',
53070      });
53071      $grid.reloadItems();
53072      $grid.layout();
53073
53074      setTimeout(function () {
53075        $grid.reloadItems();
53076        $grid.layout();
53077      }, 100);
53078
53079      $(window).on('resize', function () {
53080        $grid.reloadItems();
53081        $grid.layout();
53082      });
53083    }
53084
53085    /**
53086     * Play Button Video
53087     */
53088    if ($('.video-player').length) {
53089      /**
53090       * Insert Button
53091       */
53092      $('.video-player').each(function () {
53093        $(this).append($('<a href="#play" class="btn-video-play"></a>'));
53094      });
53095
53096      /**
53097       * Click Button Play
53098       */
53099      $(document).on('click', '.btn-video-play', function () {
53100        var video = $(this).parent().find('video');
53101
53102        if (video.get(0).paused) {
53103          video.get(0).play();
53104          $(this).fadeOut();
53105        } else {
53106          video.get(0).pause();
53107          $(this).fadeIn();
53108        }
53109      });
53110    }
53111
53112    /********************************************************************
53113     * Filter Ajax Component
53114     * News and Events
53115     * @type {{init: init}}
53116     */
53117    var FilterNewsEventAjax = (function () {
53118      /**
53119       * const
53120       * @type {{overlayCSS: {background: string, opacity: number}, message: string}}
53121       */
53122      var loader = {
53123        message: '',
53124        overlayCSS: { background: '#fff', opacity: 0.6 },
53125      };
53126
53127      /**
53128       * Ajax
53129       * @param container
53130       * @param data
53131       * @constructor
53132       */
53133      var Ajax = function (data) {
53134        if ( data === void 0 ) data = '';
53135
53136        /**
53137         *
53138         * @type {jQuery|HTMLElement}
53139         */
53140        var $container_result = $('.filterNewsEvent .resultAjax'), //Container
53141          $container_items = $container_result.find('.recfilter_section__list'), //Container Items
53142          $month_panel = $('.filterNewsEventFormMonth'), //Panel Month
53143          $form = $('.filterNewsEventForm'); //Form
53144
53145        /**
53146         * Data
53147         * @type {string}
53148         */
53149        data +=
53150          $form.serialize() + '&month=' + $('.filterNewsEventFormDate').val();
53151
53152        $.ajax({
53153          beforeSend: function () {
53154            $container_result.block(loader);
53155          },
53156          data: data,
53157          dataType: 'json',
53158          method: 'POST',
53159          complete: function () {
53160            $container_result.unblock();
53161          },
53162          success: function (data) {
53163            if (data.success === false) {
53164              $('.newsevent-masonry').addClass('recfilter_section__list-empty');
53165            } else {
53166              $('.newsevent-masonry').removeClass(
53167                'recfilter_section__list-empty'
53168              );
53169            }
53170
53171            /**
53172             * Items
53173             */
53174
53175            /**
53176             * Html
53177             */
53178            $container_items.html(data.data.html).ready(function () {
53179              var grid = new __WEBPACK_IMPORTED_MODULE_3_masonry_layout___default.a('.newsevent-masonry');
53180              grid.reloadItems();
53181              setTimeout(function () {
53182                grid = new __WEBPACK_IMPORTED_MODULE_3_masonry_layout___default.a('.newsevent-masonry', {
53183                  percentPosition: true,
53184                  itemSelector: '.item',
53185                  isInitLayout: true,
53186                  gutter: 0,
53187                  transitionDuration: 0,
53188                  columnWidth: '.grid-sizer',
53189                });
53190              }, 200);
53191            });
53192
53193            /**
53194             * Masonry
53195             */
53196            $(window).trigger('resize');
53197
53198            /**
53199             * Month Panel
53200             */
53201            $month_panel.html(data.data.month);
53202          },
53203          url: window.nec.ajax_url,
53204        });
53205      };
53206
53207      /**
53208       * News and Event
53209       * @constructor
53210       */
53211      var NewsEvent = function () {
53212        /**
53213         * Select
53214         * @change
53215         */
53216        $(document).on('change', '.filterNewsEvent select', function () {
53217          Ajax();
53218        });
53219
53220        /**
53221         * Next or Prev Month
53222         * @click
53223         */
53224        $(document).on('click', '.filterNewsEventMonth', function () {
53225          var month = $(this).data('month');
53226
53227          $('.filterNewsEventFormDate').val(month);
53228
53229          Ajax('month_custom=' + month + '&');
53230        });
53231      };
53232
53233      /**
53234       * @return
53235       */
53236      return {
53237        init: function () {
53238          NewsEvent();
53239        },
53240      };
53241    })();
53242
53243    /**
53244     * Init Filter Ajax
53245     */
53246    FilterNewsEventAjax.init();
53247
53248    /**
53249     * Filter Ajax Component
53250     * Taxonomy
53251     * @type {{init: init}}
53252     */
53253    var FilterTaxonomyAjax = (function () {
53254      /**
53255       * const
53256       * @type {{overlayCSS: {background: string, opacity: number}, message: string}}
53257       */
53258      var loader = {
53259        message: '',
53260        overlayCSS: { background: '#fff', opacity: 0.6 },
53261      };
53262
53263      /**
53264       * Ajax
53265       * @param container
53266       * @param data
53267       * @constructor
53268       */
53269      var Ajax = function (data, type) {
53270        if ( data === void 0 ) data = '';
53271        if ( type === void 0 ) type = 'post';
53272
53273        /**
53274         *
53275         * @type {jQuery|HTMLElement}
53276         */
53277        var $container = $('.resultTaxonomyAjax'),
53278          $container_result = $('.resultTaxonomyAjaxPost'),
53279          $form = $('.filterTaxonomy');
53280
53281        if ($form.length) {
53282          /**
53283           * Data
53284           * @type {string}
53285           */
53286          data +=
53287            $form.serialize() +
53288            '&level=' +
53289            $('[name=select_level]').val() +
53290            '&place=' +
53291            $('[name=select_place]').val() +
53292            '&' +
53293            '&type=' +
53294            type;
53295
53296          $.ajax({
53297            beforeSend: function () {
53298              if (type == 'post') {
53299                $container.block(loader);
53300              }
53301            },
53302            data: data,
53303            dataType: 'json',
53304            method: 'POST',
53305            complete: function () {
53306              if (type == 'post') {
53307                $container.unblock();
53308              } else {
53309                $('.taxfilter_section__filter-list--input').removeClass(
53310                  'active'
53311                );
53312              }
53313            },
53314            success: function (data) {
53315              /**
53316               * Search
53317               */
53318              if (type == 'search') {
53319                $('.filterTaxonomySearchResultTax').html(data.data.html);
53320
53321                return false;
53322              }
53323
53324              /**
53325               * Check Badges
53326               */
53327              checkSelectedBadges();
53328
53329              /**
53330               * Html
53331               */
53332              $container_result.html(data.data.html).ready(function () {});
53333              document.querySelector('.page-id-20 .taxfilter_section__ajax').style.visibility = 'visible';
53334            },
53335            url: window.nec.ajax_url,
53336          });
53337        }
53338      };
53339
53340      /**
53341       * Select Multiple
53342       * @constructor
53343       */
53344      var Select = function () {
53345        /**
53346         *
53347         */
53348        $.fn.select2.amd.require(
53349          [
53350            'select2/selection/single',
53351            'select2/selection/placeholder',
53352            'select2/dropdown',
53353            'select2/dropdown/attachBody',
53354            'select2/utils' ],
53355          function (SingleSelection, Placeholder, Dropdown, AttachBody, Utils) {
53356            var SelectionAdapter = Utils.Decorate(SingleSelection, Placeholder);
53357
53358            $('.js-select-checkbox').each(function () {
53359              var $select = $(this),
53360                placeholder = $(this).data('placeholder');
53361
53362              $select.select2({
53363                placeholder: placeholder,
53364                selectionAdapter: SelectionAdapter,
53365                closeOnSelect: false,
53366                dropdownParent: $select.parent(),
53367                templateResult: function (data) {
53368                  if (!data.id) {
53369                    return data.text;
53370                  }
53371
53372                  var $res = $('<div></div>');
53373
53374                  $res.text(data.text);
53375                  $res.addClass('wrap');
53376
53377                  $res.attr('data-name', data.text.trim());
53378                  $res.attr('data-id', data.id.trim());
53379
53380                  return $res;
53381                },
53382                templateSelection: function (data) {
53383                  if (!data.id) {
53384                    return data.text;
53385                  }
53386
53387                  var selected = ($select.val() || []).length;
53388                  var total = $('option', $select).length;
53389
53390                  return placeholder + ' (' + selected + ' of ' + total + ')';
53391                },
53392              });
53393            });
53394          }
53395        );
53396
53397        /**
53398         * Add Badges
53399         * @click
53400         */
53401        $(document).on('click', '.select2-results__option', function () {
53402          var id = $(this).find('.wrap').data('id'),
53403            name = $(this).find('.wrap').data('name');
53404          var showRow = function (filterObject, rowData, id) {
53405            var show = true;
53406            Object.entries(filterObject).forEach(function (ref) {
53407              var key = ref[0];
53408
53409              show = false;
53410              var rowArray = rowData.dataset[id]
53411                .toUpperCase()
53412                .replace(/\s/g, '')
53413                .split(',');
53414              rowArray.forEach(function (element) {
53415                if (filterObject[key].hasOwnProperty(element)) {
53416                  show = true;
53417                }
53418              });
53419              if (!show) {
53420                return false;
53421              }
53422            });
53423            return show;
53424          };
53425          if ($('.faculty_section').length) {
53426            var filterObject = {};
53427            $('.select2-results__option--selected').each(function (i, el) {
53428              var filter = $(this)
53429                .closest('.col')
53430                .find('select')[0]
53431                .dataset.placeholder.toLowerCase();
53432              var option = el.innerText.toUpperCase().replace(/\s/g, '');
53433              filterObject.hasOwnProperty(filter)
53434                ? ''
53435                : (filterObject[filter] = {});
53436              filterObject[filter][option] = 1;
53437            });
53438            var row = $('table').find('tr:not(.header)');
53439            if (!$(this).hasClass('select2-results__option--selected')) {
53440              row.each(function (i, rowData) {
53441                var show = showRow(filterObject, rowData, id);
53442                show
53443                  ? $(rowData).show().addClass('active')
53444                  : $(rowData).hide().removeClass('active');
53445              });
53446            } else {
53447              row = $('table').find('tr:not(.header)');
53448              row.each(function (i, rowData) {
53449                var show = showRow(filterObject, rowData, id);
53450                if (show === true) {
53451                  $(rowData).show().addClass('active');
53452                } else {
53453                  $(rowData).hide().removeClass('active');
53454                }
53455              });
53456            }
53457          } else {
53458            var url = window.location.origin + window.location.pathname;
53459            var params = new URLSearchParams(window.location.search);
53460            var filter = $(this.closest('.col'))
53461              .find('select')[0]
53462              .getAttribute('name');
53463            var param = 'category[]';
53464            if (filter === 'select_place') {
53465              param = 'location[]';
53466            } else if (filter === 'select_level') {
53467              param = 'level[]';
53468            }
53469            if (!$(this).hasClass('select2-results__option--selected')) {
53470              $('.filterTaxonomyBadges')
53471                .find('[data-id="' + id + '"]')
53472                .remove();
53473              var filteredParams = params
53474                .getAll(param)
53475                .filter(function (el) {
53476                  return el !== name.trim();
53477                })
53478                .map(function (el) {
53479                  return [param, el];
53480                });
53481              params.delete(param);
53482              filteredParams.map(function (el) {
53483                params.append(param, el);
53484              });
53485            } else {
53486              $('.filterTaxonomyBadges').append(
53487                '<li data-type="sellect" data-id="' +
53488                  id +
53489                  '" data-name="' +
53490                  name.trim() +
53491                  '">' +
53492                  '<a href="#remove-' +
53493                  id +
53494                  '">' +
53495                  name.trim() +
53496                  '</a>' +
53497                  '</li>'
53498              );
53499              params.append(param, name.trim());
53500            }
53501            window.history.replaceState(
53502              null,
53503              null,
53504              url + '?' + params.toString()
53505            ); // or pushState
53506
53507            /**
53508             * Return Ajax
53509             */
53510            Ajax();
53511          }
53512        });
53513
53514        Ajax();
53515      };
53516
53517      /**
53518       * Search Input
53519       * @constructor
53520       */
53521      var Search = function () {
53522        /**
53523         * @click
53524         */
53525        $(document).on('click', '.filterTaxonomySearchResultCat', function (e) {
53526          e.preventDefault();
53527          console.log('---10')
53528
53529          /**
53530           * const
53531           * @type {jQuery|HTMLElement}
53532           */
53533          var $this = $(this),
53534            id = $this.data('id'),
53535            name = $this.text().trim(),
53536            $inp_cat = $('.filterTaxonomy input[name=category]'),
53537            def_value = $inp_cat.val();
53538
53539          console.log(id,name, $inp_cat, def_value)
53540
53541          /**
53542           *
53543           */
53544          var url = window.location.origin + window.location.pathname;
53545          var params = new URLSearchParams(window.location.search);
53546          var param = 'category[]';
53547          if ($('.filterTaxonomyPanel [data-id=' + id + ']').length) {
53548            $inp_cat.val(function (index, value) {
53549              return value.replace(id + ',', '');
53550            });
53551
53552            $('.filterTaxonomyPanel [data-id=' + id + ']').remove();
53553          } else {
53554            $('.filterTaxonomyBadges').append(
53555              '<li data-type="category" data-id="' +
53556                id +
53557                '" data-name="' +
53558                name +
53559                '">' +
53560                '<a href="#remove-' +
53561                id +
53562                '">' +
53563                name +
53564                '</a>' +
53565                '</li>'
53566            );
53567            params.append(param, name.trim());
53568            $inp_cat.val(def_value + id + ',');
53569          }
53570
53571          console.log('param', url + '?' + params.toString());
53572
53573          window.history.replaceState(
53574            null,
53575            null,
53576            url + '?' + params.toString()
53577          ); // or pushState
53578          /**
53579           * Return Ajax
53580           */
53581          Ajax();
53582
53583          /**
53584           * Check Badges
53585           */
53586          checkSelectedBadges();
53587        });
53588
53589        /**
53590         * @focus
53591         */
53592        $(document).on('focus', '.filterTaxonomySearch', function () {
53593          $('.filterTaxonomySearchResult').addClass('open');
53594        });
53595
53596        /**
53597         * @focusout
53598         */
53599        $(document).on('focusout', '.filterTaxonomySearch', function () {});
53600
53601        /**
53602         * @keyup
53603         */
53604        $(document).on('keyup', '.filterTaxonomySearch', function () {
53605          var $this = $(this),
53606            value = $this.val();
53607
53608          if (value.length) {
53609            $this.parent().addClass('active');
53610            $('.filterTaxonomySearchResultDefault').hide();
53611            $('.filterTaxonomySearchResultTax').show();
53612          } else {
53613            $this.parent().removeClass('active');
53614            $('.filterTaxonomySearchResultDefault').show();
53615            $('.filterTaxonomySearchResultTax').hide();
53616          }
53617
53618          /**
53619           * Return Ajax
53620           */
53621          Ajax('', 'search');
53622        });
53623
53624        /**
53625         * Search Section Group
53626         * @mouseup
53627         */
53628        $(document).mouseup(function (e) {
53629          var div = $('.filterTaxonomySearchGroup');
53630
53631          if (!div.is(e.target) && div.has(e.target).length === 0) {
53632            $('.filterTaxonomySearchResultDefault').show();
53633            $('.filterTaxonomySearchResultTax').html('');
53634            $('.filterTaxonomySearchResult').removeClass('open');
53635            $('.filterTaxonomySearch').val('');
53636          }
53637        });
53638      };
53639
53640      /**
53641       * Panel
53642       * @constructor
53643       */
53644      var Panel = function () {
53645        /**
53646         * Remove Badges
53647         * @click
53648         */
53649        $(document).on('click', '.filterTaxonomyBadges a', function (e) {
53650          console.log('--8')
53651          var $elem = $(this).parent(),
53652            id = $elem.data('id'),
53653            type = $elem.data('type');
53654          var name = $elem.data('name');
53655          var url = window.location.origin + window.location.pathname;
53656          var params = new URLSearchParams(window.location.search);
53657          var selectBox = $('.js-select-checkbox option[value="' + id + '"]');
53658          if (type !== 'category') {
53659            var filter = $(selectBox.closest('.col'))
53660              .find('select')[0]
53661              .getAttribute('name');
53662          }
53663          var param = 'category[]';
53664          if (filter === 'select_place') {
53665            param = 'location[]';
53666          } else if (filter === 'select_level') {
53667            param = 'level[]';
53668          }
53669          var filteredParams = params
53670            .getAll(param)
53671            .filter(function (el) {
53672              return el !== name.trim();
53673            })
53674            .map(function (el) {
53675              return [param, el];
53676            });
53677          params.delete(param);
53678          filteredParams.map(function (el) {
53679            params.append(param, el);
53680          });
53681          window.history.replaceState(
53682            null,
53683            null,
53684            url + '?' + params.toString()
53685          ); // or pushState
53686
53687          $('.js-select-checkbox option[value="' + id + '"]').prop(
53688            'selected',
53689            false
53690          );
53691          $('.js-select-checkbox').trigger('change');
53692
53693          $(this).parent().remove();
53694
53695          /**
53696           * Replace Category
53697           */
53698          if (type === 'category') {
53699            $('.filterTaxonomy input[name=category]').val(function (
53700              index,
53701              value
53702            ) {
53703              return value.replace(id + ',', '');
53704            });
53705          }
53706
53707          /**
53708           * Return Ajax
53709           */
53710          Ajax();
53711
53712          /**
53713           * preventDefault
53714           */
53715          e.preventDefault();
53716        });
53717
53718        /**
53719         * Clear All Filters
53720         * @click
53721         */
53722        $(document).on('click', '.filterTaxonomyClear', function () {
53723          /**
53724           *
53725           */
53726          console.log('--11')
53727          $('.js-select-checkbox').val(null).trigger('change');
53728          $('.filterTaxonomyBadges').html('');
53729
53730          /**
53731           * Check Badges
53732           */
53733          checkSelectedBadges();
53734        });
53735
53736        /**
53737         * View List
53738         * @click
53739         */
53740        $(document).on('click', '.filterTaxonomyView', function () {
53741          $(this).toggleClass('grid');
53742
53743          $('.resultTaxonomyAjaxList').toggleClass('table');
53744        });
53745      };
53746
53747      /**
53748       * Check Badges
53749       */
53750      var checkSelectedBadges = function () {
53751        var $container = $('.filterTaxonomyPanel'),
53752          $elem = $container.find('li');
53753
53754        if ($elem.length) {
53755          $container.removeClass('hidden');
53756
53757          $('.resultTaxonomyAjaxCat').hide();
53758          $('.resultTaxonomyAjaxPost').show();
53759        } else {
53760          $container.addClass('hidden');
53761
53762          $('.resultTaxonomyAjaxCat').show();
53763          $('.resultTaxonomyAjaxPost').html('').hide();
53764        }
53765      };
53766
53767      /**
53768       * Mobile
53769       * @constructor
53770       */
53771      var Mobile = function () {
53772        /**
53773         * Mobile Filter Open
53774         * @click
53775         */
53776        $(document).on('click', '.filterTaxonomyMobileBtn', function (e) {
53777          $('body').toggleClass('no-scroll');
53778          $('.filterTaxonomyMobilePopup').toggleClass('active');
53779
53780          e.preventDefault();
53781        });
53782      };
53783
53784      /**
53785       * @return
53786       */
53787      return {
53788        init: function () {
53789          Select();
53790          Search();
53791          Panel();
53792          Mobile();
53793        },
53794      };
53795    })();
53796    /**
53797     * Init Filter Ajax
53798     */
53799    FilterTaxonomyAjax.init();
53800  },
53801});
53802
53803/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(2)))
53804
53805/***/ }),
53806/* 254 */
53807/***/ (function(module, __webpack_exports__, __webpack_require__) {
53808
53809"use strict";
53810/* WEBPACK VAR INJECTION */(function($) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_masonry_layout__ = __webpack_require__(7);
53811/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_masonry_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_masonry_layout__);
53812/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_fabric_dist_fabric__ = __webpack_require__(255);
53813/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_fabric_dist_fabric___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_fabric_dist_fabric__);
53814/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__panzoom_panzoom_dist_panzoom__ = __webpack_require__(264);
53815/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__panzoom_panzoom_dist_panzoom___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2__panzoom_panzoom_dist_panzoom__);
53816/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_swiper_bundle__ = __webpack_require__(6);
53817/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_jquery_ui_ui_widgets_draggable__ = __webpack_require__(265);
53818/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_jquery_ui_ui_widgets_draggable___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_jquery_ui_ui_widgets_draggable__);
53819
53820
53821
53822
53823
53824
53825/* harmony default export */ __webpack_exports__["a"] = ({
53826  init: function init() {
53827    // JavaScript to be fired on the about us page
53828  },
53829  finalize: function finalize() {
53830
53831    /**
53832     * Masonry Downloads
53833     * @click
53834     */
53835    if( $('.masonry-downloads').length ) {
53836
53837      /**
53838       *
53839       */
53840      $( '.masonry-downloads' ).each(function(index) {
53841
53842        var $elem = 'masonry-downloads-' + index;
53843
53844        $(this).addClass($elem);
53845
53846        var $masonry = '.' + $elem;
53847
53848        /**
53849         * Grid
53850         */
53851        var $grid = {};
53852
53853        $grid[index] = new __WEBPACK_IMPORTED_MODULE_0_masonry_layout___default.a($masonry, {
53854          percentPosition   :   true,
53855          itemSelector      :   '.masonry-downloads-item',
53856          gutter            :   0,
53857          transitionDuration:   0,
53858          columnWidth       :   '.grid-sizer',
53859        });
53860
53861        /**
53862         * Load and Resize
53863         */
53864        $(window).on('load resize', function () {
53865          $grid[index].reloadItems();
53866          $grid[index].layout();
53867        });
53868
53869        /**
53870         * Accordion
53871         * @click
53872         */
53873        $(document).on('click', $masonry + ' .accordion-downloads-title', function(e){
53874
53875          var $li         = $(this).parent(),
53876            $html       = $li.find('.accordion-downloads-body'),
53877            program_ID  = $(this).data('program'),
53878            catalog_ID  = $(this).data('catalog'),
53879            course_ID   = $(this).data('course');
53880
53881          if( $li.hasClass('active') ) {
53882
53883            $($masonry + ' .accordion-downloads').find('.active').removeClass('active');
53884
53885          }else{
53886
53887            $($masonry + ' .accordion-downloads').find('.active').removeClass('active');
53888            $li.addClass('active');
53889
53890            if( !$html.html().length ) {
53891
53892              $.ajax( {
53893                beforeSend  :   function(){
53894                  $li.block({message : '', overlayCSS : {background : '#fff', opacity : 0.6}});
53895                },
53896                data        :   {
53897                  action      :   'courses',
53898                  catalog_id  :   catalog_ID,
53899                  program_id  :   program_ID,
53900                  course_id   :   course_ID,
53901                },
53902                dataType    :   'json',
53903                method      :   'POST',
53904                complete    :   function(){
53905                  $li.unblock();
53906                },
53907                success     :   function( data ){
53908
53909                  $html.html(data.data.html);
53910
53911                  $grid[index].reloadItems();
53912                  $grid[index].layout();
53913
53914                },
53915                url         :   window.nec.ajax_url,
53916              } );
53917
53918            }
53919
53920          }
53921
53922          /**
53923           * Masonry reinit
53924           */
53925          if (typeof $grid[index] !== 'undefined') {
53926            $grid[index].reloadItems();
53927            $grid[index].layout();
53928          }
53929
53930          /**
53931           *
53932           */
53933          e.preventDefault();
53934
53935        });
53936
53937      });
53938
53939    }
53940
53941    /**
53942     * Accordion
53943     * @click
53944     */
53945    if( $('.accordion').length ) {
53946
53947      $(document).on('click', '.accordion-title', function(e){
53948
53949        var $li = $(this).parent();
53950
53951        if( $li.hasClass('active') ) {
53952
53953          $('.accordion').find('.active').removeClass('active');
53954
53955        }else{
53956
53957          $('.accordion').find('.active').removeClass('active');
53958          $li.addClass('active');
53959
53960        }
53961
53962        e.preventDefault();
53963
53964      });
53965
53966    }
53967
53968    /**
53969     * Play Button
53970     */
53971    if($('.newssingle__content .wp-block-video').length) {
53972
53973      /**
53974       * Insert Button
53975       */
53976      $( '.newssingle__content .wp-block-video' ).each(function() {
53977
53978        $(this).append($('<a href="#play" class="btn-video-play"></a>'));
53979
53980      });
53981
53982      /**
53983       * Click Button Play
53984       */
53985      $(document).on('click', '.btn-video-play', function(){
53986
53987        var video = $(this).parent().find('video');
53988
53989        if(video.get(0).paused){
53990
53991          video.get(0).play();
53992          $(this).fadeOut();
53993
53994        }else{
53995
53996          video.get(0).pause();
53997          $(this).fadeIn();
53998
53999        }
54000
54001      });
54002
54003    }
54004
54005
54006    /**
54007     * TourMap
54008     * @type {{init: init}}
54009     */
54010    var TourMapSingle = function () {
54011
54012      /**
54013       * Global
54014       * @type {number}
54015       */
54016      var CONFIG = {
54017        marker_default_color  : '#CB333B',
54018        point_default_color   : '#00226B',
54019      },
54020        // eslint-disable-next-line no-unused-vars
54021        TOOLTIP_VISIBLE   = 0,
54022        TOOLTIP_TIMER     = null,
54023        TOOLTIP_TIMER_2   = null,
54024        CLICKED_MARKER    = 0,
54025        ACTIVE_OBJECT     = 0,
54026        canvas            = new __WEBPACK_IMPORTED_MODULE_1_fabric_dist_fabric__["fabric"].Canvas('tour-canvas', {
54027          hoverCursor             : 'pointer',
54028          preserveObjectStacking  : false,
54029          enableRetinaScaling     : false,
54030          imageSmoothingEnabled   : false,
54031        });
54032
54033      /**
54034       * Install
54035       * @param data
54036       * @constructor
54037       */
54038      var Install = function () {
54039
54040        /**
54041         * Global
54042         * @type {number}
54043         */
54044
54045        var map_json = $('.map_tour__inner').data('json');
54046
54047        canvas.loadFromJSON(map_json, function() {
54048
54049          canvas.renderAll();
54050          canvas.forEachObject(function(object){
54051
54052            object.selectable = false;
54053
54054              /**
54055               * Click
54056               */
54057              object.on('mousedown', function(e) {
54058
54059                //e.target._objects[0];
54060
54061                if( e.target ) {
54062
54063                  $('.map_tour__tooltip').removeClass('active');
54064
54065                  if( e.target.element_type === 'marker' ) {
54066
54067                    SetObjectHoverStyle(e);
54068
54069                    CLICKED_MARKER = 1;
54070                    ACTIVE_OBJECT = e.target.id;
54071                    LoadDetail(e);
54072
54073
54074                  }
54075                }
54076
54077              });
54078
54079              /**
54080               * Over Object
54081               */
54082              object.on('mouseover', function(e) {
54083
54084                if( e.target ) {
54085
54086                  SetObjectHoverStyle(e);
54087
54088                  if( CLICKED_MARKER === 0 ) { Tooltip(e, 'over') }
54089
54090                }
54091
54092              });
54093
54094              /**
54095               * Out Object
54096               */
54097              object.on('mouseout', function(e) {
54098
54099                if( e.target ) {
54100
54101                  if( CLICKED_MARKER === 0 ) { Tooltip(e, 'out') }
54102
54103                }
54104
54105              });
54106
54107          });
54108
54109        }, function(){
54110
54111          var window_w = $(window).width() / 2,
54112              window_h = $(window).height() / 2,
54113              canvas_w = (canvas.width / 2) - window_w,
54114              canvas_h = (canvas.height / 2) - window_h;
54115
54116          $('.canvas-container').css({
54117            left  : -canvas_w,
54118            top   : -canvas_h,
54119          });
54120
54121        });
54122
54123        __WEBPACK_IMPORTED_MODULE_1_fabric_dist_fabric__["fabric"].Object.prototype.transparentCorners = false;
54124        canvas.selection = false;
54125
54126        var element = document.querySelectorAll('.canvas-container'),
54127              zoomInButton = document.getElementById('map_tour_zoomIn'),
54128              zoomOutButton = document.getElementById('map_tour_zoomOut');
54129
54130        var panzoom;
54131
54132        for (var i = 0; i < element.length; i++) {
54133
54134          panzoom = __WEBPACK_IMPORTED_MODULE_2__panzoom_panzoom_dist_panzoom___default()(element[i], {
54135            animate     : true,
54136            duration    : 600,
54137            maxScale    : 1.9,
54138            minScale    : 0.5,
54139            step        : 0.1,
54140            canvas      : false,
54141            //contain     : 'outside',
54142            disablePan  : false,
54143            exclude: ['circle', 'group'],
54144            // eslint-disable-next-line no-unused-vars
54145            handleStartEvent: function (e) {
54146              // e.preventDefault();
54147              // e.stopPropagation();
54148            },
54149          });
54150
54151          element[i].addEventListener('panzoomchange', function (event) {
54152            if( event.detail.scale === 1 ) {
54153              console.dir('panzoom disable');
54154              panzoom.destroy();
54155            }
54156          });
54157
54158        }
54159
54160        zoomInButton.addEventListener('click', panzoom.zoomIn);
54161        zoomOutButton.addEventListener('click', panzoom.zoomOut);
54162
54163        //panzoom.destroy()
54164
54165
54166        /**
54167         * Open Detail Tour
54168         * @tourOpenDetail
54169         */
54170        $(document).on('click', '.tourOpenDetail', function() {
54171
54172          var $this   = $(this),
54173                post    = $this.data('id'),
54174                left    = $this.data('left'),
54175                right   = $this.data('right'),
54176                id_element = $this.data('element');
54177
54178          CLICKED_MARKER = 1;
54179
54180          ACTIVE_OBJECT = id_element;
54181          LoadDetail({ target: { left: left, right: right } }, post, id_element);
54182
54183        });
54184
54185        /**
54186         * Expand Post Full Width
54187         * @tourTextExpand
54188         */
54189        $(document).on('click', '.tourTextExpand', function(e){
54190
54191          e.preventDefault();
54192
54193          $('.map_detail').toggleClass('full');
54194          $('.header_tour__breadcrumbs').toggleClass('hide');
54195
54196        });
54197
54198        /**
54199         * Close Right Panel
54200         * @tourClosePanel
54201         */
54202        $(document).on('click', '.tourClosePanel', function(e){
54203
54204          e.preventDefault();
54205
54206          $('.map_tour').removeClass('tour__read');
54207          $('.map_detail').removeClass('full');
54208          $('.canvas-container').find('.map_tour__tooltip').removeClass('active');
54209
54210          $('.tourNextItem, .tourPrevItem').show()
54211
54212          /**
54213           * Show Objects
54214           * @HideObjects
54215           */
54216          CLICKED_MARKER = 0;
54217          HideObjects(null, 'show');
54218
54219        });
54220
54221        /**
54222         * Next Post
54223         * @tourNextItem
54224         */
54225        $(document).on('click', '.tourNextItem', function(e){
54226
54227          e.preventDefault();
54228
54229          Navigations('next');
54230
54231        });
54232
54233        /**
54234         * Prev Post
54235         * @tourPrevItem
54236         */
54237        $(document).on('click', '.tourPrevItem', function(e){
54238
54239          e.preventDefault();
54240
54241          Navigations('prev');
54242
54243        });
54244
54245      }
54246
54247      /**
54248       *
54249       * @param e
54250       * @param type
54251       * @constructor
54252       */
54253      var Tooltip = function (e, type) {
54254
54255        var $canvas_container = $('.canvas-container'),
54256            $tooltip          = $('.map_tour__tooltip');
54257
54258        if( !$canvas_container.find('.map_tour__tooltip').length ) {
54259          $canvas_container.append($tooltip.clone());
54260        }
54261
54262        $tooltip = $('.canvas-container').find('.map_tour__tooltip');
54263
54264        if( 'out' === type ) {
54265
54266          clearTimeout(TOOLTIP_TIMER_2);
54267          TOOLTIP_TIMER = setTimeout( function () {
54268
54269              $tooltip.removeClass('active');
54270              clearTimeout(TOOLTIP_TIMER_2);
54271              TOOLTIP_VISIBLE = 0;
54272              ResetObjects();
54273
54274          }, 500);
54275
54276        }else{
54277
54278          clearTimeout(TOOLTIP_TIMER_2);
54279          clearTimeout(TOOLTIP_TIMER);
54280          TOOLTIP_VISIBLE = 1;
54281
54282          /**
54283           *
54284           */
54285          $tooltip.html('');
54286
54287          var marker_link = '';
54288          if( e.target.element_type == 'marker' ) {
54289            marker_link = '<a href="#modal-right" class="link tourOpenDetail" data-id="' + e.target.element_tour_id + '" data-left="' + e.target.left + '" data-right="' + e.target.right + '" data-element="' + e.target.id + '">Learn More</a>';
54290          }
54291
54292          $tooltip.append(
54293            '<div class="map_tour__tooltip__marker">' +
54294            '<h3 class="title">' +
54295            e.target.element_tooltip +
54296            '</h3>' +
54297            marker_link +
54298            '</div>'
54299          ).ready(function () {
54300
54301            // eslint-disable-next-line no-unused-vars
54302            var h_tooltip = $tooltip.outerHeight(true),
54303                w_tooltip = $tooltip.outerWidth(true),
54304                h_element = e.target.height,
54305                w_element = e.target.width;
54306
54307            $tooltip.css({
54308              left: ((e.target.left - ( w_tooltip / 2 )) + ( w_element / 2 )) - 8,
54309              top: ((e.target.top - h_tooltip) - ( h_element / 2 )) + 8,
54310            });
54311
54312            $tooltip.addClass('active');
54313
54314          });
54315
54316
54317          $tooltip.mouseenter(function() {
54318
54319            $tooltip.addClass('active');
54320            TOOLTIP_VISIBLE = 1;
54321            clearTimeout(TOOLTIP_TIMER);
54322            clearTimeout(TOOLTIP_TIMER_2);
54323
54324          }).mouseleave(function() {
54325
54326            TOOLTIP_TIMER_2 = setTimeout( function () {
54327
54328                TOOLTIP_VISIBLE = 0;
54329                $tooltip.removeClass('active');
54330                clearTimeout(TOOLTIP_TIMER);
54331                ResetObjects();
54332
54333
54334            }, 500);
54335
54336            clearTimeout(TOOLTIP_TIMER);
54337
54338          });
54339
54340        }
54341
54342      }
54343
54344      /**
54345       *
54346       * @param e
54347       * @param type
54348       * @constructor
54349       */
54350      var LoadDetail = function (e, post, element, navigation) {
54351        if ( post === void 0 ) post = 0;
54352        if ( element === void 0 ) element = 0;
54353        if ( navigation === void 0 ) navigation = false;
54354
54355
54356        /**
54357         *
54358     */
54359        if( element > 0 ) {
54360          canvas.forEachObject(function(object){
54361            if( object.id === element ) { e = { target: object }; }
54362          });
54363        }
54364
54365        /**
54366         * Center Map
54367         * @type {number}
54368         */
54369        var window_w = $(window).width() / 2,
54370            window_h = $(window).height() / 2,
54371            canvas_w = e.target.left - ( window_w / 2 ),
54372            canvas_h = e.target.top - window_h;
54373
54374        $('.canvas-container').stop().animate({
54375          left: -canvas_w,
54376          top: -canvas_h,
54377        });
54378
54379        if( post === 0 ) {
54380          post = e.target.element_tour_id;
54381        }
54382
54383        /**
54384         * Hide Objects
54385         * @HideObjects
54386         */
54387
54388        HideObjects(e, 'hide');
54389
54390        /**
54391         *
54392         */
54393        if( true === navigation ) { e.target.opacity = 1; }
54394
54395
54396        /**
54397         * Ajax
54398         */
54399
54400        $.ajax( {
54401
54402            beforeSend  :   function(){
54403
54404              $('.tourDetailAjax').html('');
54405              $('.map_tour').addClass('tour__read');
54406              $('.map_detail__content').addClass('preloader');
54407
54408            },
54409            data        :   {
54410              action    :   'tour_get_item',
54411              post      :   post,
54412            },
54413            dataType    :   'json',
54414            method      :   'POST',
54415            complete    :   function(){ },
54416            // eslint-disable-next-line no-unused-vars
54417            success     :   function( response ){
54418
54419              $('.map_detail__content').removeClass('preloader');
54420              $('.tourDetailAjax').html(response.data.html).ready(function(){
54421
54422                if( $('.wp-swiper').length ) {
54423
54424                  // eslint-disable-next-line no-unused-vars
54425                  var swiper = new __WEBPACK_IMPORTED_MODULE_3_swiper_bundle__["a" /* default */]('.wp-swiper .swiper-container', {
54426                    speed         : 400,
54427                    autoHeight: true, //enable auto height
54428
54429                    spaceBetween    : 0,
54430        effect          :'fade',
54431        pagination      : {
54432          el            : '.swiper-pagination',
54433          clickable     : true,
54434          type          : 'bullets',
54435        },
54436        navigation: {
54437          nextEl        : '.swiper-button-next',
54438          prevEl        : '.swiper-button-prev',
54439        },
54440      });
54441    }
54442
54443              });
54444
54445            },
54446            // eslint-disable-next-line no-undef
54447            url         :   nec.ajax_url,
54448          } );
54449
54450      }
54451
54452    /**
54453       *
54454       * @param e
54455       * @param type
54456       * @constructor
54457     */
54458      var DragMap = function () {
54459
54460        $('.canvas-container').draggable({
54461          drag : function(event,ui){
54462            var parent = ui.helper[0].parentNode;
54463
54464            var dragWidth = ui.helper[0].clientWidth;
54465            var parentWidth = parent.clientWidth;
54466            var dragHeight = ui.helper[0].clientHeight;
54467            var parentHeight = parent.clientHeight;
54468
54469            var widthDifference = dragWidth - parentWidth;
54470            var heightDifference = dragHeight - parentHeight;
54471
54472            if(ui.position.left > 0) { ui.position.left = 0; }
54473            else if(ui.position.left < -widthDifference) { ui.position.left = -widthDifference; }
54474
54475            if(ui.position.top > 0) { ui.position.top = 0; }
54476            else if(ui.position.top < -heightDifference) { ui.position.top = -heightDifference; }
54477
54478        },
54479        });
54480
54481        // let drag = false;
54482        //
54483        // $('.canvas-container').on('mousedown touchstart', function(){
54484        //   drag = true;
54485        // }).on('mouseup mouseout', function(){
54486        //   $(this).data({
54487        //     startX: 0,
54488        //     startY: 0,
54489        //   });
54490        //   drag = false;
54491        // }).on('mousemove touchmove', function(e){
54492        //   e.preventDefault();
54493        //   if(drag){
54494        //     //console.log($(this).data(),e);
54495        //     var left = parseInt($(this).css('left')) || 0,
54496        //       top = parseInt($(this).css('top')) || 0,
54497        //       newLeft = left + (e.clientX - ($(this).data().startX || e.clientX)),
54498        //       newTop  = top + (e.clientY - ($(this).data().startY || e.clientY)),
54499        //       parentHeight = $(this).parent().height(),
54500        //       parentWidth = $(this).parent().width(),
54501        //       imgHeight = $(this).height(),
54502        //       imgWidth = $(this).width();
54503        //
54504        //     $(this).css({
54505        //       left: newLeft < 0 && (Math.abs(newLeft - parentWidth) < imgWidth) ? newLeft : left,
54506        //       top: newTop < 0 && (Math.abs(newTop - parentHeight) < imgHeight) ? newTop : top,
54507        //     }).data({
54508        //       startX: e.clientX,
54509        //       startY: e.clientY,
54510        //     });
54511        //
54512        //   }
54513        // });
54514
54515      }
54516
54517      /**
54518       *
54519       * @constructor
54520       */
54521      var HideObjects = function (e, type) {
54522
54523        if( 'show' === type ) { ResetObjects() }
54524
54525        // eslint-disable-next-line no-unused-vars
54526        canvas.forEachObject(function(object){
54527
54528          if( 'hide' === type ) {
54529
54530            // eslint-disable-next-line no-unused-vars
54531            var element_click = e.target.id;
54532
54533            if( element_click != object.id ) {
54534
54535              object.opacity = 0;
54536
54537            }else{
54538
54539              SetObjectHoverStyle({ target: object})
54540
54541            }
54542
54543            canvas.renderAll();
54544
54545          }
54546
54547
54548        })
54549
54550      }
54551
54552      /**
54553       *
54554       * @param e
54555       * @constructor
54556       */
54557      var SetObjectHoverStyle = function (e) {
54558
54559        e.target._objects[0].set('opacity', 1);
54560        e.target._objects[0].set('fill', 'black');
54561        e.target._objects[0].set('strokeWidth', 6);
54562        e.target._objects[0].set('stroke', 'rgba(0,0,0,0.3)');
54563        canvas.renderAll();
54564
54565      }
54566
54567      /**
54568       *
54569       * @constructor
54570       */
54571      var ResetObjects = function () {
54572
54573        if( CLICKED_MARKER == 0 ) {
54574          canvas.forEachObject(function (object) {
54575
54576            if (object.element_type === 'marker') {
54577              object._objects[0].set('fill', CONFIG.marker_default_color);
54578            } else if (object.element_type === 'point') {
54579              object._objects[0].set('fill', CONFIG.point_default_color);
54580            }
54581            object._objects[0].set('strokeWidth', 2);
54582            object._objects[0].set('stroke', 'white');
54583            object.opacity = 1;
54584
54585          })
54586          canvas.renderAll();
54587        }
54588
54589      }
54590
54591      /**
54592       *
54593       * @constructor
54594       */
54595      var Navigations = function (type) {
54596
54597        var $next_button = $('.tourNextItem'),
54598            $prev_button = $('.tourPrevItem')
54599        /**
54600         *
54601         */
54602        var obj = [];
54603        canvas.getObjects().forEach(function(o) {
54604
54605          if( o.element_type == 'marker' ) {
54606            obj.push(o);
54607          }
54608
54609        })
54610
54611        // eslint-disable-next-line no-unused-vars
54612        var it = 0,
54613          // eslint-disable-next-line no-unused-vars
54614          bty = [];
54615
54616        // eslint-disable-next-line no-unused-vars
54617        $.each(obj, function( index, value ) {
54618
54619          if( value.id === ACTIVE_OBJECT ) {
54620
54621            if( 'next' === type ) { bty = obj[index + 1]; }
54622            if( 'prev' === type ) { bty = obj[index - 1]; }
54623
54624          }
54625
54626      });
54627
54628        var last_item_arr = [];
54629        if( undefined == bty ) {
54630
54631          if( 'next' === type ) { $next_button.hide(); }
54632          if( 'prev' === type ) { $prev_button.hide(); }
54633
54634        }else{
54635
54636          if (Object.keys(bty).length > 0) {
54637
54638            ACTIVE_OBJECT = bty.id
54639
54640            LoadDetail({target: bty}, bty.element_tour_id, bty.id, true);
54641            SetObjectHoverStyle({target: bty})
54642
54643            /**
54644             * Last Item Array
54645             * @type {*}
54646             */
54647            last_item_arr = obj.slice(-1).pop();
54648
54649          }
54650
54651          if( 'next' === type ) {
54652            $prev_button.show()
54653            if( last_item_arr.id === bty.id ) {
54654              $next_button.hide()
54655            }
54656          }
54657
54658          if( 'prev' === type ) {
54659            $next_button.show()
54660            if( obj[0].id === bty.id ) {
54661              $prev_button.hide()
54662    }
54663          }
54664
54665        }
54666
54667      }
54668
54669      /**
54670       * @return
54671       */
54672      return {
54673        init: function () {
54674          Install();
54675          DragMap();
54676        },
54677      };
54678    }();
54679
54680    /**
54681     * Init TourMap
54682     */
54683    if( $('#tour-canvas').length ) {
54684      TourMapSingle.init();
54685    }
54686
54687
54688
54689
54690
54691
54692  },
54693});
54694
54695/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(2)))
54696
54697/***/ }),
54698/* 255 */
54699/***/ (function(module, exports, __webpack_require__) {
54700
54701/* WEBPACK VAR INJECTION */(function(Buffer) {/* build: `node build.js modules=ALL exclude=gestures,accessors,erasing requirejs minifier=uglifyjs` */
54702/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
54703
54704var fabric = fabric || { version: '4.6.0' };
54705if (true) {
54706  exports.fabric = fabric;
54707}
54708/* _AMD_START_ */
54709else if (typeof define === 'function' && define.amd) {
54710  define([], function() { return fabric; });
54711}
54712/* _AMD_END_ */
54713if (typeof document !== 'undefined' && typeof window !== 'undefined') {
54714  if (document instanceof (typeof HTMLDocument !== 'undefined' ? HTMLDocument : Document)) {
54715    fabric.document = document;
54716  }
54717  else {
54718    fabric.document = document.implementation.createHTMLDocument('');
54719  }
54720  fabric.window = window;
54721}
54722else {
54723  // assume we're running under node.js when document/window are not present
54724  var jsdom = __webpack_require__(261);
54725  var virtualWindow = new jsdom.JSDOM(
54726    decodeURIComponent('%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E'),
54727    {
54728      features: {
54729        FetchExternalResources: ['img']
54730      },
54731      resources: 'usable'
54732    }).window;
54733  fabric.document = virtualWindow.document;
54734  fabric.jsdomImplForWrapper = __webpack_require__(262).implForWrapper;
54735  fabric.nodeCanvas = __webpack_require__(263
vendor: 52,368 bytes, lines 54735-56394
54735).Canvas;
54736  fabric.window = virtualWindow;
54737  DOMParser = fabric.window.DOMParser;
54738}
54739
54740/**
54741 * True when in environment that supports touch events
54742 * @type boolean
54743 */
54744fabric.isTouchSupported = 'ontouchstart' in fabric.window || 'ontouchstart' in fabric.document ||
54745  (fabric.window && fabric.window.navigator && fabric.window.navigator.maxTouchPoints > 0);
54746
54747/**
54748 * True when in environment that's probably Node.js
54749 * @type boolean
54750 */
54751fabric.isLikelyNode = typeof Buffer !== 'undefined' &&
54752                      typeof window === 'undefined';
54753
54754/* _FROM_SVG_START_ */
54755/**
54756 * Attributes parsed from all SVG elements
54757 * @type array
54758 */
54759fabric.SHARED_ATTRIBUTES = [
54760  'display',
54761  'transform',
54762  'fill', 'fill-opacity', 'fill-rule',
54763  'opacity',
54764  'stroke', 'stroke-dasharray', 'stroke-linecap', 'stroke-dashoffset',
54765  'stroke-linejoin', 'stroke-miterlimit',
54766  'stroke-opacity', 'stroke-width',
54767  'id', 'paint-order', 'vector-effect',
54768  'instantiated_by_use', 'clip-path',
54769];
54770/* _FROM_SVG_END_ */
54771
54772/**
54773 * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion.
54774 */
54775fabric.DPI = 96;
54776fabric.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:[eE][-+]?\\d+)?)';
54777fabric.commaWsp = '(?:\\s+,?\\s*|,\\s*)';
54778fabric.rePathCommand = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:[eE][-+]?\d+)?)/ig;
54779fabric.reNonWord = /[ \n\.,;!\?\-]/;
54780fabric.fontPaths = { };
54781fabric.iMatrix = [1, 0, 0, 1, 0, 0];
54782fabric.svgNS = 'http://www.w3.org/2000/svg';
54783
54784/**
54785 * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine.
54786 * @since 1.7.14
54787 * @type Number
54788 * @default
54789 */
54790fabric.perfLimitSizeTotal = 2097152;
54791
54792/**
54793 * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000
54794 * @since 1.7.14
54795 * @type Number
54796 * @default
54797 */
54798fabric.maxCacheSideLimit = 4096;
54799
54800/**
54801 * Lowest pixel limit for cache canvases, set at 256PX
54802 * @since 1.7.14
54803 * @type Number
54804 * @default
54805 */
54806fabric.minCacheSideLimit = 256;
54807
54808/**
54809 * Cache Object for widths of chars in text rendering.
54810 */
54811fabric.charWidthsCache = { };
54812
54813/**
54814 * if webgl is enabled and available, textureSize will determine the size
54815 * of the canvas backend
54816 * @since 2.0.0
54817 * @type Number
54818 * @default
54819 */
54820fabric.textureSize = 2048;
54821
54822/**
54823 * When 'true', style information is not retained when copy/pasting text, making
54824 * pasted text use destination style.
54825 * Defaults to 'false'.
54826 * @type Boolean
54827 * @default
54828 */
54829fabric.disableStyleCopyPaste = false;
54830
54831/**
54832 * Enable webgl for filtering picture is available
54833 * A filtering backend will be initialized, this will both take memory and
54834 * time since a default 2048x2048 canvas will be created for the gl context
54835 * @since 2.0.0
54836 * @type Boolean
54837 * @default
54838 */
54839fabric.enableGLFiltering = true;
54840
54841/**
54842 * Device Pixel Ratio
54843 * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html
54844 */
54845fabric.devicePixelRatio = fabric.window.devicePixelRatio ||
54846                          fabric.window.webkitDevicePixelRatio ||
54847                          fabric.window.mozDevicePixelRatio ||
54848                          1;
54849/**
54850 * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value,
54851 * which is unitless and not rendered equally across browsers.
54852 *
54853 * Values that work quite well (as of October 2017) are:
54854 * - Chrome: 1.5
54855 * - Edge: 1.75
54856 * - Firefox: 0.9
54857 * - Safari: 0.95
54858 *
54859 * @since 2.0.0
54860 * @type Number
54861 * @default 1
54862 */
54863fabric.browserShadowBlurConstant = 1;
54864
54865/**
54866 * This object contains the result of arc to bezier conversion for faster retrieving if the same arc needs to be converted again.
54867 * It was an internal variable, is accessible since version 2.3.4
54868 */
54869fabric.arcToSegmentsCache = { };
54870
54871/**
54872 * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.
54873 * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing
54874 * you do not get any speed benefit and you get a big object in memory.
54875 * The object was a private variable before, while now is appended to the lib so that you have access to it and you
54876 * can eventually clear it.
54877 * It was an internal variable, is accessible since version 2.3.4
54878 */
54879fabric.boundsOfCurveCache = { };
54880
54881/**
54882 * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better
54883 * @default true
54884 */
54885fabric.cachesBoundsOfCurve = true;
54886
54887/**
54888 * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on
54889 * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true
54890 * this has to be set before instantiating the filtering backend ( before filtering the first image )
54891 * @type Boolean
54892 * @default false
54893 */
54894fabric.forceGLPutImageData = false;
54895
54896fabric.initFilterBackend = function() {
54897  if (fabric.enableGLFiltering && fabric.isWebglSupported && fabric.isWebglSupported(fabric.textureSize)) {
54898    console.log('max texture size: ' + fabric.maxTextureSize);
54899    return (new fabric.WebglFilterBackend({ tileSize: fabric.textureSize }));
54900  }
54901  else if (fabric.Canvas2dFilterBackend) {
54902    return (new fabric.Canvas2dFilterBackend());
54903  }
54904};
54905
54906
54907if (typeof document !== 'undefined' && typeof window !== 'undefined') {
54908  // ensure globality even if entire library were function wrapped (as in Meteor.js packaging system)
54909  window.fabric = fabric;
54910}
54911
54912
54913(function() {
54914
54915  /**
54916   * @private
54917   * @param {String} eventName
54918   * @param {Function} handler
54919   */
54920  function _removeEventListener(eventName, handler) {
54921    if (!this.__eventListeners[eventName]) {
54922      return;
54923    }
54924    var eventListener = this.__eventListeners[eventName];
54925    if (handler) {
54926      eventListener[eventListener.indexOf(handler)] = false;
54927    }
54928    else {
54929      fabric.util.array.fill(eventListener, false);
54930    }
54931  }
54932
54933  /**
54934   * Observes specified event
54935   * @memberOf fabric.Observable
54936   * @alias on
54937   * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})
54938   * @param {Function} handler Function that receives a notification when an event of the specified type occurs
54939   * @return {Self} thisArg
54940   * @chainable
54941   */
54942  function on(eventName, handler) {
54943    if (!this.__eventListeners) {
54944      this.__eventListeners = { };
54945    }
54946    // one object with key/value pairs was passed
54947    if (arguments.length === 1) {
54948      for (var prop in eventName) {
54949        this.on(prop, eventName[prop]);
54950      }
54951    }
54952    else {
54953      if (!this.__eventListeners[eventName]) {
54954        this.__eventListeners[eventName] = [];
54955      }
54956      this.__eventListeners[eventName].push(handler);
54957    }
54958    return this;
54959  }
54960
54961  function _once(eventName, handler) {
54962    var _handler = function () {
54963      handler.apply(this, arguments);
54964      this.off(eventName, _handler);
54965    }.bind(this);
54966    this.on(eventName, _handler);
54967  }
54968
54969  function once(eventName, handler) {
54970    // one object with key/value pairs was passed
54971    if (arguments.length === 1) {
54972      for (var prop in eventName) {
54973        _once.call(this, prop, eventName[prop]);
54974      }
54975    }
54976    else {
54977      _once.call(this, eventName, handler);
54978    }
54979    return this;
54980  }
54981
54982  /**
54983   * Stops event observing for a particular event handler. Calling this method
54984   * without arguments removes all handlers for all events
54985   * @memberOf fabric.Observable
54986   * @alias off
54987   * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})
54988   * @param {Function} handler Function to be deleted from EventListeners
54989   * @return {Self} thisArg
54990   * @chainable
54991   */
54992  function off(eventName, handler) {
54993    if (!this.__eventListeners) {
54994      return this;
54995    }
54996
54997    // remove all key/value pairs (event name -> event handler)
54998    if (arguments.length === 0) {
54999      for (eventName in this.__eventListeners) {
55000        _removeEventListener.call(this, eventName);
55001      }
55002    }
55003    // one object with key/value pairs was passed
55004    else if (arguments.length === 1 && typeof arguments[0] === 'object') {
55005      for (var prop in eventName) {
55006        _removeEventListener.call(this, prop, eventName[prop]);
55007      }
55008    }
55009    else {
55010      _removeEventListener.call(this, eventName, handler);
55011    }
55012    return this;
55013  }
55014
55015  /**
55016   * Fires event with an optional options object
55017   * @memberOf fabric.Observable
55018   * @param {String} eventName Event name to fire
55019   * @param {Object} [options] Options object
55020   * @return {Self} thisArg
55021   * @chainable
55022   */
55023  function fire(eventName, options) {
55024    if (!this.__eventListeners) {
55025      return this;
55026    }
55027
55028    var listenersForEvent = this.__eventListeners[eventName];
55029    if (!listenersForEvent) {
55030      return this;
55031    }
55032
55033    for (var i = 0, len = listenersForEvent.length; i < len; i++) {
55034      listenersForEvent[i] && listenersForEvent[i].call(this, options || { });
55035    }
55036    this.__eventListeners[eventName] = listenersForEvent.filter(function(value) {
55037      return value !== false;
55038    });
55039    return this;
55040  }
55041
55042  /**
55043   * @namespace fabric.Observable
55044   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events}
55045   * @see {@link http://fabricjs.com/events|Events demo}
55046   */
55047  fabric.Observable = {
55048    fire: fire,
55049    on: on,
55050    once: once,
55051    off: off,
55052  };
55053})();
55054
55055
55056/**
55057 * @namespace fabric.Collection
55058 */
55059fabric.Collection = {
55060
55061  _objects: [],
55062
55063  /**
55064   * Adds objects to collection, Canvas or Group, then renders canvas
55065   * (if `renderOnAddRemove` is not `false`).
55066   * in case of Group no changes to bounding box are made.
55067   * Objects should be instances of (or inherit from) fabric.Object
55068   * Use of this function is highly discouraged for groups.
55069   * you can add a bunch of objects with the add method but then you NEED
55070   * to run a addWithUpdate call for the Group class or position/bbox will be wrong.
55071   * @param {...fabric.Object} object Zero or more fabric instances
55072   * @return {Self} thisArg
55073   * @chainable
55074   */
55075  add: function () {
55076    this._objects.push.apply(this._objects, arguments);
55077    if (this._onObjectAdded) {
55078      for (var i = 0, length = arguments.length; i < length; i++) {
55079        this._onObjectAdded(arguments[i]);
55080      }
55081    }
55082    this.renderOnAddRemove && this.requestRenderAll();
55083    return this;
55084  },
55085
55086  /**
55087   * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`)
55088   * An object should be an instance of (or inherit from) fabric.Object
55089   * Use of this function is highly discouraged for groups.
55090   * you can add a bunch of objects with the insertAt method but then you NEED
55091   * to run a addWithUpdate call for the Group class or position/bbox will be wrong.
55092   * @param {Object} object Object to insert
55093   * @param {Number} index Index to insert object at
55094   * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs
55095   * @return {Self} thisArg
55096   * @chainable
55097   */
55098  insertAt: function (object, index, nonSplicing) {
55099    var objects = this._objects;
55100    if (nonSplicing) {
55101      objects[index] = object;
55102    }
55103    else {
55104      objects.splice(index, 0, object);
55105    }
55106    this._onObjectAdded && this._onObjectAdded(object);
55107    this.renderOnAddRemove && this.requestRenderAll();
55108    return this;
55109  },
55110
55111  /**
55112   * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`)
55113   * @param {...fabric.Object} object Zero or more fabric instances
55114   * @return {Self} thisArg
55115   * @chainable
55116   */
55117  remove: function() {
55118    var objects = this._objects,
55119        index, somethingRemoved = false;
55120
55121    for (var i = 0, length = arguments.length; i < length; i++) {
55122      index = objects.indexOf(arguments[i]);
55123
55124      // only call onObjectRemoved if an object was actually removed
55125      if (index !== -1) {
55126        somethingRemoved = true;
55127        objects.splice(index, 1);
55128        this._onObjectRemoved && this._onObjectRemoved(arguments[i]);
55129      }
55130    }
55131
55132    this.renderOnAddRemove && somethingRemoved && this.requestRenderAll();
55133    return this;
55134  },
55135
55136  /**
55137   * Executes given function for each object in this group
55138   * @param {Function} callback
55139   *                   Callback invoked with current object as first argument,
55140   *                   index - as second and an array of all objects - as third.
55141   *                   Callback is invoked in a context of Global Object (e.g. `window`)
55142   *                   when no `context` argument is given
55143   *
55144   * @param {Object} context Context (aka thisObject)
55145   * @return {Self} thisArg
55146   * @chainable
55147   */
55148  forEachObject: function(callback, context) {
55149    var objects = this.getObjects();
55150    for (var i = 0, len = objects.length; i < len; i++) {
55151      callback.call(context, objects[i], i, objects);
55152    }
55153    return this;
55154  },
55155
55156  /**
55157   * Returns an array of children objects of this instance
55158   * Type parameter introduced in 1.3.10
55159   * since 2.3.5 this method return always a COPY of the array;
55160   * @param {String} [type] When specified, only objects of this type are returned
55161   * @return {Array}
55162   */
55163  getObjects: function(type) {
55164    if (typeof type === 'undefined') {
55165      return this._objects.concat();
55166    }
55167    return this._objects.filter(function(o) {
55168      return o.type === type;
55169    });
55170  },
55171
55172  /**
55173   * Returns object at specified index
55174   * @param {Number} index
55175   * @return {Self} thisArg
55176   */
55177  item: function (index) {
55178    return this._objects[index];
55179  },
55180
55181  /**
55182   * Returns true if collection contains no objects
55183   * @return {Boolean} true if collection is empty
55184   */
55185  isEmpty: function () {
55186    return this._objects.length === 0;
55187  },
55188
55189  /**
55190   * Returns a size of a collection (i.e: length of an array containing its objects)
55191   * @return {Number} Collection size
55192   */
55193  size: function() {
55194    return this._objects.length;
55195  },
55196
55197  /**
55198   * Returns true if collection contains an object
55199   * @param {Object} object Object to check against
55200   * @param {Boolean} [deep=false] `true` to check all descendants, `false` to check only `_objects`
55201   * @return {Boolean} `true` if collection contains an object
55202   */
55203  contains: function (object, deep) {
55204    if (this._objects.indexOf(object) > -1) {
55205      return true;
55206    }
55207    else if (deep) {
55208      return this._objects.some(function (obj) {
55209        return typeof obj.contains === 'function' && obj.contains(object, true);
55210      });
55211    }
55212    return false;
55213  },
55214
55215  /**
55216   * Returns number representation of a collection complexity
55217   * @return {Number} complexity
55218   */
55219  complexity: function () {
55220    return this._objects.reduce(function (memo, current) {
55221      memo += current.complexity ? current.complexity() : 0;
55222      return memo;
55223    }, 0);
55224  }
55225};
55226
55227
55228/**
55229 * @namespace fabric.CommonMethods
55230 */
55231fabric.CommonMethods = {
55232
55233  /**
55234   * Sets object's properties from options
55235   * @param {Object} [options] Options object
55236   */
55237  _setOptions: function(options) {
55238    for (var prop in options) {
55239      this.set(prop, options[prop]);
55240    }
55241  },
55242
55243  /**
55244   * @private
55245   * @param {Object} [filler] Options object
55246   * @param {String} [property] property to set the Gradient to
55247   */
55248  _initGradient: function(filler, property) {
55249    if (filler && filler.colorStops && !(filler instanceof fabric.Gradient)) {
55250      this.set(property, new fabric.Gradient(filler));
55251    }
55252  },
55253
55254  /**
55255   * @private
55256   * @param {Object} [filler] Options object
55257   * @param {String} [property] property to set the Pattern to
55258   * @param {Function} [callback] callback to invoke after pattern load
55259   */
55260  _initPattern: function(filler, property, callback) {
55261    if (filler && filler.source && !(filler instanceof fabric.Pattern)) {
55262      this.set(property, new fabric.Pattern(filler, callback));
55263    }
55264    else {
55265      callback && callback();
55266    }
55267  },
55268
55269  /**
55270   * @private
55271   */
55272  _setObject: function(obj) {
55273    for (var prop in obj) {
55274      this._set(prop, obj[prop]);
55275    }
55276  },
55277
55278  /**
55279   * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.
55280   * @param {String|Object} key Property name or object (if object, iterate over the object properties)
55281   * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)
55282   * @return {fabric.Object} thisArg
55283   * @chainable
55284   */
55285  set: function(key, value) {
55286    if (typeof key === 'object') {
55287      this._setObject(key);
55288    }
55289    else {
55290      this._set(key, value);
55291    }
55292    return this;
55293  },
55294
55295  _set: function(key, value) {
55296    this[key] = value;
55297  },
55298
55299  /**
55300   * Toggles specified property from `true` to `false` or from `false` to `true`
55301   * @param {String} property Property to toggle
55302   * @return {fabric.Object} thisArg
55303   * @chainable
55304   */
55305  toggle: function(property) {
55306    var value = this.get(property);
55307    if (typeof value === 'boolean') {
55308      this.set(property, !value);
55309    }
55310    return this;
55311  },
55312
55313  /**
55314   * Basic getter
55315   * @param {String} property Property name
55316   * @return {*} value of a property
55317   */
55318  get: function(property) {
55319    return this[property];
55320  }
55321};
55322
55323
55324(function(global) {
55325
55326  var sqrt = Math.sqrt,
55327      atan2 = Math.atan2,
55328      pow = Math.pow,
55329      PiBy180 = Math.PI / 180,
55330      PiBy2 = Math.PI / 2;
55331
55332  /**
55333   * @namespace fabric.util
55334   */
55335  fabric.util = {
55336
55337    /**
55338     * Calculate the cos of an angle, avoiding returning floats for known results
55339     * @static
55340     * @memberOf fabric.util
55341     * @param {Number} angle the angle in radians or in degree
55342     * @return {Number}
55343     */
55344    cos: function(angle) {
55345      if (angle === 0) { return 1; }
55346      if (angle < 0) {
55347        // cos(a) = cos(-a)
55348        angle = -angle;
55349      }
55350      var angleSlice = angle / PiBy2;
55351      switch (angleSlice) {
55352        case 1: case 3: return 0;
55353        case 2: return -1;
55354      }
55355      return Math.cos(angle);
55356    },
55357
55358    /**
55359     * Calculate the sin of an angle, avoiding returning floats for known results
55360     * @static
55361     * @memberOf fabric.util
55362     * @param {Number} angle the angle in radians or in degree
55363     * @return {Number}
55364     */
55365    sin: function(angle) {
55366      if (angle === 0) { return 0; }
55367      var angleSlice = angle / PiBy2, sign = 1;
55368      if (angle < 0) {
55369        // sin(-a) = -sin(a)
55370        sign = -1;
55371      }
55372      switch (angleSlice) {
55373        case 1: return sign;
55374        case 2: return 0;
55375        case 3: return -sign;
55376      }
55377      return Math.sin(angle);
55378    },
55379
55380    /**
55381     * Removes value from an array.
55382     * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`
55383     * @static
55384     * @memberOf fabric.util
55385     * @param {Array} array
55386     * @param {*} value
55387     * @return {Array} original array
55388     */
55389    removeFromArray: function(array, value) {
55390      var idx = array.indexOf(value);
55391      if (idx !== -1) {
55392        array.splice(idx, 1);
55393      }
55394      return array;
55395    },
55396
55397    /**
55398     * Returns random number between 2 specified ones.
55399     * @static
55400     * @memberOf fabric.util
55401     * @param {Number} min lower limit
55402     * @param {Number} max upper limit
55403     * @return {Number} random value (between min and max)
55404     */
55405    getRandomInt: function(min, max) {
55406      return Math.floor(Math.random() * (max - min + 1)) + min;
55407    },
55408
55409    /**
55410     * Transforms degrees to radians.
55411     * @static
55412     * @memberOf fabric.util
55413     * @param {Number} degrees value in degrees
55414     * @return {Number} value in radians
55415     */
55416    degreesToRadians: function(degrees) {
55417      return degrees * PiBy180;
55418    },
55419
55420    /**
55421     * Transforms radians to degrees.
55422     * @static
55423     * @memberOf fabric.util
55424     * @param {Number} radians value in radians
55425     * @return {Number} value in degrees
55426     */
55427    radiansToDegrees: function(radians) {
55428      return radians / PiBy180;
55429    },
55430
55431    /**
55432     * Rotates `point` around `origin` with `radians`
55433     * @static
55434     * @memberOf fabric.util
55435     * @param {fabric.Point} point The point to rotate
55436     * @param {fabric.Point} origin The origin of the rotation
55437     * @param {Number} radians The radians of the angle for the rotation
55438     * @return {fabric.Point} The new rotated point
55439     */
55440    rotatePoint: function(point, origin, radians) {
55441      var newPoint = new fabric.Point(point.x - origin.x, point.y - origin.y),
55442          v = fabric.util.rotateVector(newPoint, radians);
55443      return new fabric.Point(v.x, v.y).addEquals(origin);
55444    },
55445
55446    /**
55447     * Rotates `vector` with `radians`
55448     * @static
55449     * @memberOf fabric.util
55450     * @param {Object} vector The vector to rotate (x and y)
55451     * @param {Number} radians The radians of the angle for the rotation
55452     * @return {Object} The new rotated point
55453     */
55454    rotateVector: function(vector, radians) {
55455      var sin = fabric.util.sin(radians),
55456          cos = fabric.util.cos(radians),
55457          rx = vector.x * cos - vector.y * sin,
55458          ry = vector.x * sin + vector.y * cos;
55459      return {
55460        x: rx,
55461        y: ry
55462      };
55463    },
55464
55465    /**
55466     * Apply transform t to point p
55467     * @static
55468     * @memberOf fabric.util
55469     * @param  {fabric.Point} p The point to transform
55470     * @param  {Array} t The transform
55471     * @param  {Boolean} [ignoreOffset] Indicates that the offset should not be applied
55472     * @return {fabric.Point} The transformed point
55473     */
55474    transformPoint: function(p, t, ignoreOffset) {
55475      if (ignoreOffset) {
55476        return new fabric.Point(
55477          t[0] * p.x + t[2] * p.y,
55478          t[1] * p.x + t[3] * p.y
55479        );
55480      }
55481      return new fabric.Point(
55482        t[0] * p.x + t[2] * p.y + t[4],
55483        t[1] * p.x + t[3] * p.y + t[5]
55484      );
55485    },
55486
55487    /**
55488     * Returns coordinates of points's bounding rectangle (left, top, width, height)
55489     * @param {Array} points 4 points array
55490     * @param {Array} [transform] an array of 6 numbers representing a 2x3 transform matrix
55491     * @return {Object} Object with left, top, width, height properties
55492     */
55493    makeBoundingBoxFromPoints: function(points, transform) {
55494      if (transform) {
55495        for (var i = 0; i < points.length; i++) {
55496          points[i] = fabric.util.transformPoint(points[i], transform);
55497        }
55498      }
55499      var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x],
55500          minX = fabric.util.array.min(xPoints),
55501          maxX = fabric.util.array.max(xPoints),
55502          width = maxX - minX,
55503          yPoints = [points[0].y, points[1].y, points[2].y, points[3].y],
55504          minY = fabric.util.array.min(yPoints),
55505          maxY = fabric.util.array.max(yPoints),
55506          height = maxY - minY;
55507
55508      return {
55509        left: minX,
55510        top: minY,
55511        width: width,
55512        height: height
55513      };
55514    },
55515
55516    /**
55517     * Invert transformation t
55518     * @static
55519     * @memberOf fabric.util
55520     * @param {Array} t The transform
55521     * @return {Array} The inverted transform
55522     */
55523    invertTransform: function(t) {
55524      var a = 1 / (t[0] * t[3] - t[1] * t[2]),
55525          r = [a * t[3], -a * t[1], -a * t[2], a * t[0]],
55526          o = fabric.util.transformPoint({ x: t[4], y: t[5] }, r, true);
55527      r[4] = -o.x;
55528      r[5] = -o.y;
55529      return r;
55530    },
55531
55532    /**
55533     * A wrapper around Number#toFixed, which contrary to native method returns number, not string.
55534     * @static
55535     * @memberOf fabric.util
55536     * @param {Number|String} number number to operate on
55537     * @param {Number} fractionDigits number of fraction digits to "leave"
55538     * @return {Number}
55539     */
55540    toFixed: function(number, fractionDigits) {
55541      return parseFloat(Number(number).toFixed(fractionDigits));
55542    },
55543
55544    /**
55545     * Converts from attribute value to pixel value if applicable.
55546     * Returns converted pixels or original value not converted.
55547     * @param {Number|String} value number to operate on
55548     * @param {Number} fontSize
55549     * @return {Number|String}
55550     */
55551    parseUnit: function(value, fontSize) {
55552      var unit = /\D{0,2}$/.exec(value),
55553          number = parseFloat(value);
55554      if (!fontSize) {
55555        fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;
55556      }
55557      switch (unit[0]) {
55558        case 'mm':
55559          return number * fabric.DPI / 25.4;
55560
55561        case 'cm':
55562          return number * fabric.DPI / 2.54;
55563
55564        case 'in':
55565          return number * fabric.DPI;
55566
55567        case 'pt':
55568          return number * fabric.DPI / 72; // or * 4 / 3
55569
55570        case 'pc':
55571          return number * fabric.DPI / 72 * 12; // or * 16
55572
55573        case 'em':
55574          return number * fontSize;
55575
55576        default:
55577          return number;
55578      }
55579    },
55580
55581    /**
55582     * Function which always returns `false`.
55583     * @static
55584     * @memberOf fabric.util
55585     * @return {Boolean}
55586     */
55587    falseFunction: function() {
55588      return false;
55589    },
55590
55591    /**
55592     * Returns klass "Class" object of given namespace
55593     * @memberOf fabric.util
55594     * @param {String} type Type of object (eg. 'circle')
55595     * @param {String} namespace Namespace to get klass "Class" object from
55596     * @return {Object} klass "Class"
55597     */
55598    getKlass: function(type, namespace) {
55599      // capitalize first letter only
55600      type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1));
55601      return fabric.util.resolveNamespace(namespace)[type];
55602    },
55603
55604    /**
55605     * Returns array of attributes for given svg that fabric parses
55606     * @memberOf fabric.util
55607     * @param {String} type Type of svg element (eg. 'circle')
55608     * @return {Array} string names of supported attributes
55609     */
55610    getSvgAttributes: function(type) {
55611      var attributes = [
55612        'instantiated_by_use',
55613        'style',
55614        'id',
55615        'class'
55616      ];
55617      switch (type) {
55618        case 'linearGradient':
55619          attributes = attributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']);
55620          break;
55621        case 'radialGradient':
55622          attributes = attributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']);
55623          break;
55624        case 'stop':
55625          attributes = attributes.concat(['offset', 'stop-color', 'stop-opacity']);
55626          break;
55627      }
55628      return attributes;
55629    },
55630
55631    /**
55632     * Returns object of given namespace
55633     * @memberOf fabric.util
55634     * @param {String} namespace Namespace string e.g. 'fabric.Image.filter' or 'fabric'
55635     * @return {Object} Object for given namespace (default fabric)
55636     */
55637    resolveNamespace: function(namespace) {
55638      if (!namespace) {
55639        return fabric;
55640      }
55641
55642      var parts = namespace.split('.'),
55643          len = parts.length, i,
55644          obj = global || fabric.window;
55645
55646      for (i = 0; i < len; ++i) {
55647        obj = obj[parts[i]];
55648      }
55649
55650      return obj;
55651    },
55652
55653    /**
55654     * Loads image element from given url and passes it to a callback
55655     * @memberOf fabric.util
55656     * @param {String} url URL representing an image
55657     * @param {Function} callback Callback; invoked with loaded image
55658     * @param {*} [context] Context to invoke callback in
55659     * @param {Object} [crossOrigin] crossOrigin value to set image element to
55660     */
55661    loadImage: function(url, callback, context, crossOrigin) {
55662      if (!url) {
55663        callback && callback.call(context, url);
55664        return;
55665      }
55666
55667      var img = fabric.util.createImage();
55668
55669      /** @ignore */
55670      var onLoadCallback = function () {
55671        callback && callback.call(context, img, false);
55672        img = img.onload = img.onerror = null;
55673      };
55674
55675      img.onload = onLoadCallback;
55676      /** @ignore */
55677      img.onerror = function() {
55678        fabric.log('Error loading ' + img.src);
55679        callback && callback.call(context, null, true);
55680        img = img.onload = img.onerror = null;
55681      };
55682
55683      // data-urls appear to be buggy with crossOrigin
55684      // https://github.com/kangax/fabric.js/commit/d0abb90f1cd5c5ef9d2a94d3fb21a22330da3e0a#commitcomment-4513767
55685      // see https://code.google.com/p/chromium/issues/detail?id=315152
55686      //     https://bugzilla.mozilla.org/show_bug.cgi?id=935069
55687      // crossOrigin null is the same as not set.
55688      if (url.indexOf('data') !== 0 &&
55689        crossOrigin !== undefined &&
55690        crossOrigin !== null) {
55691        img.crossOrigin = crossOrigin;
55692      }
55693
55694      // IE10 / IE11-Fix: SVG contents from data: URI
55695      // will only be available if the IMG is present
55696      // in the DOM (and visible)
55697      if (url.substring(0,14) === 'data:image/svg') {
55698        img.onload = null;
55699        fabric.util.loadImageInDom(img, onLoadCallback);
55700      }
55701
55702      img.src = url;
55703    },
55704
55705    /**
55706     * Attaches SVG image with data: URL to the dom
55707     * @memberOf fabric.util
55708     * @param {Object} img Image object with data:image/svg src
55709     * @param {Function} callback Callback; invoked with loaded image
55710     * @return {Object} DOM element (div containing the SVG image)
55711     */
55712    loadImageInDom: function(img, onLoadCallback) {
55713      var div = fabric.document.createElement('div');
55714      div.style.width = div.style.height = '1px';
55715      div.style.left = div.style.top = '-100%';
55716      div.style.position = 'absolute';
55717      div.appendChild(img);
55718      fabric.document.querySelector('body').appendChild(div);
55719      /**
55720       * Wrap in function to:
55721       *   1. Call existing callback
55722       *   2. Cleanup DOM
55723       */
55724      img.onload = function () {
55725        onLoadCallback();
55726        div.parentNode.removeChild(div);
55727        div = null;
55728      };
55729    },
55730
55731    /**
55732     * Creates corresponding fabric instances from their object representations
55733     * @static
55734     * @memberOf fabric.util
55735     * @param {Array} objects Objects to enliven
55736     * @param {Function} callback Callback to invoke when all objects are created
55737     * @param {String} namespace Namespace to get klass "Class" object from
55738     * @param {Function} reviver Method for further parsing of object elements,
55739     * called after each fabric object created.
55740     */
55741    enlivenObjects: function(objects, callback, namespace, reviver) {
55742      objects = objects || [];
55743
55744      var enlivenedObjects = [],
55745          numLoadedObjects = 0,
55746          numTotalObjects = objects.length;
55747
55748      function onLoaded() {
55749        if (++numLoadedObjects === numTotalObjects) {
55750          callback && callback(enlivenedObjects.filter(function(obj) {
55751            // filter out undefined objects (objects that gave error)
55752            return obj;
55753          }));
55754        }
55755      }
55756
55757      if (!numTotalObjects) {
55758        callback && callback(enlivenedObjects);
55759        return;
55760      }
55761
55762      objects.forEach(function (o, index) {
55763        // if sparse array
55764        if (!o || !o.type) {
55765          onLoaded();
55766          return;
55767        }
55768        var klass = fabric.util.getKlass(o.type, namespace);
55769        klass.fromObject(o, function (obj, error) {
55770          error || (enlivenedObjects[index] = obj);
55771          reviver && reviver(o, obj, error);
55772          onLoaded();
55773        });
55774      });
55775    },
55776
55777    /**
55778     * Create and wait for loading of patterns
55779     * @static
55780     * @memberOf fabric.util
55781     * @param {Array} patterns Objects to enliven
55782     * @param {Function} callback Callback to invoke when all objects are created
55783     * called after each fabric object created.
55784     */
55785    enlivenPatterns: function(patterns, callback) {
55786      patterns = patterns || [];
55787
55788      function onLoaded() {
55789        if (++numLoadedPatterns === numPatterns) {
55790          callback && callback(enlivenedPatterns);
55791        }
55792      }
55793
55794      var enlivenedPatterns = [],
55795          numLoadedPatterns = 0,
55796          numPatterns = patterns.length;
55797
55798      if (!numPatterns) {
55799        callback && callback(enlivenedPatterns);
55800        return;
55801      }
55802
55803      patterns.forEach(function (p, index) {
55804        if (p && p.source) {
55805          new fabric.Pattern(p, function(pattern) {
55806            enlivenedPatterns[index] = pattern;
55807            onLoaded();
55808          });
55809        }
55810        else {
55811          enlivenedPatterns[index] = p;
55812          onLoaded();
55813        }
55814      });
55815    },
55816
55817    /**
55818     * Groups SVG elements (usually those retrieved from SVG document)
55819     * @static
55820     * @memberOf fabric.util
55821     * @param {Array} elements SVG elements to group
55822     * @param {Object} [options] Options object
55823     * @param {String} path Value to set sourcePath to
55824     * @return {fabric.Object|fabric.Group}
55825     */
55826    groupSVGElements: function(elements, options, path) {
55827      var object;
55828      if (elements && elements.length === 1) {
55829        return elements[0];
55830      }
55831      if (options) {
55832        if (options.width && options.height) {
55833          options.centerPoint = {
55834            x: options.width / 2,
55835            y: options.height / 2
55836          };
55837        }
55838        else {
55839          delete options.width;
55840          delete options.height;
55841        }
55842      }
55843      object = new fabric.Group(elements, options);
55844      if (typeof path !== 'undefined') {
55845        object.sourcePath = path;
55846      }
55847      return object;
55848    },
55849
55850    /**
55851     * Populates an object with properties of another object
55852     * @static
55853     * @memberOf fabric.util
55854     * @param {Object} source Source object
55855     * @param {Object} destination Destination object
55856     * @return {Array} properties Properties names to include
55857     */
55858    populateWithProperties: function(source, destination, properties) {
55859      if (properties && Object.prototype.toString.call(properties) === '[object Array]') {
55860        for (var i = 0, len = properties.length; i < len; i++) {
55861          if (properties[i] in source) {
55862            destination[properties[i]] = source[properties[i]];
55863          }
55864        }
55865      }
55866    },
55867
55868    /**
55869     * WARNING: THIS WAS TO SUPPORT OLD BROWSERS. deprecated.
55870     * WILL BE REMOVED IN FABRIC 5.0
55871     * Draws a dashed line between two points
55872     *
55873     * This method is used to draw dashed line around selection area.
55874     * See <a href="http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas">dotted stroke in canvas</a>
55875     *
55876     * @param {CanvasRenderingContext2D} ctx context
55877     * @param {Number} x  start x coordinate
55878     * @param {Number} y start y coordinate
55879     * @param {Number} x2 end x coordinate
55880     * @param {Number} y2 end y coordinate
55881     * @param {Array} da dash array pattern
55882     * @deprecated
55883     */
55884    drawDashedLine: function(ctx, x, y, x2, y2, da) {
55885      var dx = x2 - x,
55886          dy = y2 - y,
55887          len = sqrt(dx * dx + dy * dy),
55888          rot = atan2(dy, dx),
55889          dc = da.length,
55890          di = 0,
55891          draw = true;
55892
55893      ctx.save();
55894      ctx.translate(x, y);
55895      ctx.moveTo(0, 0);
55896      ctx.rotate(rot);
55897
55898      x = 0;
55899      while (len > x) {
55900        x += da[di++ % dc];
55901        if (x > len) {
55902          x = len;
55903        }
55904        ctx[draw ? 'lineTo' : 'moveTo'](x, 0);
55905        draw = !draw;
55906      }
55907
55908      ctx.restore();
55909    },
55910
55911    /**
55912     * Creates canvas element
55913     * @static
55914     * @memberOf fabric.util
55915     * @return {CanvasElement} initialized canvas element
55916     */
55917    createCanvasElement: function() {
55918      return fabric.document.createElement('canvas');
55919    },
55920
55921    /**
55922     * Creates a canvas element that is a copy of another and is also painted
55923     * @param {CanvasElement} canvas to copy size and content of
55924     * @static
55925     * @memberOf fabric.util
55926     * @return {CanvasElement} initialized canvas element
55927     */
55928    copyCanvasElement: function(canvas) {
55929      var newCanvas = fabric.util.createCanvasElement();
55930      newCanvas.width = canvas.width;
55931      newCanvas.height = canvas.height;
55932      newCanvas.getContext('2d').drawImage(canvas, 0, 0);
55933      return newCanvas;
55934    },
55935
55936    /**
55937     * since 2.6.0 moved from canvas instance to utility.
55938     * @param {CanvasElement} canvasEl to copy size and content of
55939     * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too
55940     * @param {Number} quality <= 1 and > 0
55941     * @static
55942     * @memberOf fabric.util
55943     * @return {String} data url
55944     */
55945    toDataURL: function(canvasEl, format, quality) {
55946      return canvasEl.toDataURL('image/' + format, quality);
55947    },
55948
55949    /**
55950     * Creates image element (works on client and node)
55951     * @static
55952     * @memberOf fabric.util
55953     * @return {HTMLImageElement} HTML image element
55954     */
55955    createImage: function() {
55956      return fabric.document.createElement('img');
55957    },
55958
55959    /**
55960     * Multiply matrix A by matrix B to nest transformations
55961     * @static
55962     * @memberOf fabric.util
55963     * @param  {Array} a First transformMatrix
55964     * @param  {Array} b Second transformMatrix
55965     * @param  {Boolean} is2x2 flag to multiply matrices as 2x2 matrices
55966     * @return {Array} The product of the two transform matrices
55967     */
55968    multiplyTransformMatrices: function(a, b, is2x2) {
55969      // Matrix multiply a * b
55970      return [
55971        a[0] * b[0] + a[2] * b[1],
55972        a[1] * b[0] + a[3] * b[1],
55973        a[0] * b[2] + a[2] * b[3],
55974        a[1] * b[2] + a[3] * b[3],
55975        is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4],
55976        is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5]
55977      ];
55978    },
55979
55980    /**
55981     * Decomposes standard 2x3 matrix into transform components
55982     * @static
55983     * @memberOf fabric.util
55984     * @param  {Array} a transformMatrix
55985     * @return {Object} Components of transform
55986     */
55987    qrDecompose: function(a) {
55988      var angle = atan2(a[1], a[0]),
55989          denom = pow(a[0], 2) + pow(a[1], 2),
55990          scaleX = sqrt(denom),
55991          scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX,
55992          skewX = atan2(a[0] * a[2] + a[1] * a [3], denom);
55993      return {
55994        angle: angle / PiBy180,
55995        scaleX: scaleX,
55996        scaleY: scaleY,
55997        skewX: skewX / PiBy180,
55998        skewY: 0,
55999        translateX: a[4],
56000        translateY: a[5]
56001      };
56002    },
56003
56004    /**
56005     * Returns a transform matrix starting from an object of the same kind of
56006     * the one returned from qrDecompose, useful also if you want to calculate some
56007     * transformations from an object that is not enlived yet
56008     * @static
56009     * @memberOf fabric.util
56010     * @param  {Object} options
56011     * @param  {Number} [options.angle] angle in degrees
56012     * @return {Number[]} transform matrix
56013     */
56014    calcRotateMatrix: function(options) {
56015      if (!options.angle) {
56016        return fabric.iMatrix.concat();
56017      }
56018      var theta = fabric.util.degreesToRadians(options.angle),
56019          cos = fabric.util.cos(theta),
56020          sin = fabric.util.sin(theta);
56021      return [cos, sin, -sin, cos, 0, 0];
56022    },
56023
56024    /**
56025     * Returns a transform matrix starting from an object of the same kind of
56026     * the one returned from qrDecompose, useful also if you want to calculate some
56027     * transformations from an object that is not enlived yet.
56028     * is called DimensionsTransformMatrix because those properties are the one that influence
56029     * the size of the resulting box of the object.
56030     * @static
56031     * @memberOf fabric.util
56032     * @param  {Object} options
56033     * @param  {Number} [options.scaleX]
56034     * @param  {Number} [options.scaleY]
56035     * @param  {Boolean} [options.flipX]
56036     * @param  {Boolean} [options.flipY]
56037     * @param  {Number} [options.skewX]
56038     * @param  {Number} [options.skewX]
56039     * @return {Number[]} transform matrix
56040     */
56041    calcDimensionsMatrix: function(options) {
56042      var scaleX = typeof options.scaleX === 'undefined' ? 1 : options.scaleX,
56043          scaleY = typeof options.scaleY === 'undefined' ? 1 : options.scaleY,
56044          scaleMatrix = [
56045            options.flipX ? -scaleX : scaleX,
56046            0,
56047            0,
56048            options.flipY ? -scaleY : scaleY,
56049            0,
56050            0],
56051          multiply = fabric.util.multiplyTransformMatrices,
56052          degreesToRadians = fabric.util.degreesToRadians;
56053      if (options.skewX) {
56054        scaleMatrix = multiply(
56055          scaleMatrix,
56056          [1, 0, Math.tan(degreesToRadians(options.skewX)), 1],
56057          true);
56058      }
56059      if (options.skewY) {
56060        scaleMatrix = multiply(
56061          scaleMatrix,
56062          [1, Math.tan(degreesToRadians(options.skewY)), 0, 1],
56063          true);
56064      }
56065      return scaleMatrix;
56066    },
56067
56068    /**
56069     * Returns a transform matrix starting from an object of the same kind of
56070     * the one returned from qrDecompose, useful also if you want to calculate some
56071     * transformations from an object that is not enlived yet
56072     * @static
56073     * @memberOf fabric.util
56074     * @param  {Object} options
56075     * @param  {Number} [options.angle]
56076     * @param  {Number} [options.scaleX]
56077     * @param  {Number} [options.scaleY]
56078     * @param  {Boolean} [options.flipX]
56079     * @param  {Boolean} [options.flipY]
56080     * @param  {Number} [options.skewX]
56081     * @param  {Number} [options.skewX]
56082     * @param  {Number} [options.translateX]
56083     * @param  {Number} [options.translateY]
56084     * @return {Number[]} transform matrix
56085     */
56086    composeMatrix: function(options) {
56087      var matrix = [1, 0, 0, 1, options.translateX || 0, options.translateY || 0],
56088          multiply = fabric.util.multiplyTransformMatrices;
56089      if (options.angle) {
56090        matrix = multiply(matrix, fabric.util.calcRotateMatrix(options));
56091      }
56092      if (options.scaleX !== 1 || options.scaleY !== 1 ||
56093          options.skewX || options.skewY || options.flipX || options.flipY) {
56094        matrix = multiply(matrix, fabric.util.calcDimensionsMatrix(options));
56095      }
56096      return matrix;
56097    },
56098
56099    /**
56100     * reset an object transform state to neutral. Top and left are not accounted for
56101     * @static
56102     * @memberOf fabric.util
56103     * @param  {fabric.Object} target object to transform
56104     */
56105    resetObjectTransform: function (target) {
56106      target.scaleX = 1;
56107      target.scaleY = 1;
56108      target.skewX = 0;
56109      target.skewY = 0;
56110      target.flipX = false;
56111      target.flipY = false;
56112      target.rotate(0);
56113    },
56114
56115    /**
56116     * Extract Object transform values
56117     * @static
56118     * @memberOf fabric.util
56119     * @param  {fabric.Object} target object to read from
56120     * @return {Object} Components of transform
56121     */
56122    saveObjectTransform: function (target) {
56123      return {
56124        scaleX: target.scaleX,
56125        scaleY: target.scaleY,
56126        skewX: target.skewX,
56127        skewY: target.skewY,
56128        angle: target.angle,
56129        left: target.left,
56130        flipX: target.flipX,
56131        flipY: target.flipY,
56132        top: target.top
56133      };
56134    },
56135
56136    /**
56137     * Returns true if context has transparent pixel
56138     * at specified location (taking tolerance into account)
56139     * @param {CanvasRenderingContext2D} ctx context
56140     * @param {Number} x x coordinate
56141     * @param {Number} y y coordinate
56142     * @param {Number} tolerance Tolerance
56143     */
56144    isTransparent: function(ctx, x, y, tolerance) {
56145
56146      // If tolerance is > 0 adjust start coords to take into account.
56147      // If moves off Canvas fix to 0
56148      if (tolerance > 0) {
56149        if (x > tolerance) {
56150          x -= tolerance;
56151        }
56152        else {
56153          x = 0;
56154        }
56155        if (y > tolerance) {
56156          y -= tolerance;
56157        }
56158        else {
56159          y = 0;
56160        }
56161      }
56162
56163      var _isTransparent = true, i, temp,
56164          imageData = ctx.getImageData(x, y, (tolerance * 2) || 1, (tolerance * 2) || 1),
56165          l = imageData.data.length;
56166
56167      // Split image data - for tolerance > 1, pixelDataSize = 4;
56168      for (i = 3; i < l; i += 4) {
56169        temp = imageData.data[i];
56170        _isTransparent = temp <= 0;
56171        if (_isTransparent === false) {
56172          break; // Stop if colour found
56173        }
56174      }
56175
56176      imageData = null;
56177
56178      return _isTransparent;
56179    },
56180
56181    /**
56182     * Parse preserveAspectRatio attribute from element
56183     * @param {string} attribute to be parsed
56184     * @return {Object} an object containing align and meetOrSlice attribute
56185     */
56186    parsePreserveAspectRatioAttribute: function(attribute) {
56187      var meetOrSlice = 'meet', alignX = 'Mid', alignY = 'Mid',
56188          aspectRatioAttrs = attribute.split(' '), align;
56189
56190      if (aspectRatioAttrs && aspectRatioAttrs.length) {
56191        meetOrSlice = aspectRatioAttrs.pop();
56192        if (meetOrSlice !== 'meet' && meetOrSlice !== 'slice') {
56193          align = meetOrSlice;
56194          meetOrSlice = 'meet';
56195        }
56196        else if (aspectRatioAttrs.length) {
56197          align = aspectRatioAttrs.pop();
56198        }
56199      }
56200      //divide align in alignX and alignY
56201      alignX = align !== 'none' ? align.slice(1, 4) : 'none';
56202      alignY = align !== 'none' ? align.slice(5, 8) : 'none';
56203      return {
56204        meetOrSlice: meetOrSlice,
56205        alignX: alignX,
56206        alignY: alignY
56207      };
56208    },
56209
56210    /**
56211     * Clear char widths cache for the given font family or all the cache if no
56212     * fontFamily is specified.
56213     * Use it if you know you are loading fonts in a lazy way and you are not waiting
56214     * for custom fonts to load properly when adding text objects to the canvas.
56215     * If a text object is added when its own font is not loaded yet, you will get wrong
56216     * measurement and so wrong bounding boxes.
56217     * After the font cache is cleared, either change the textObject text content or call
56218     * initDimensions() to trigger a recalculation
56219     * @memberOf fabric.util
56220     * @param {String} [fontFamily] font family to clear
56221     */
56222    clearFabricFontCache: function(fontFamily) {
56223      fontFamily = (fontFamily || '').toLowerCase();
56224      if (!fontFamily) {
56225        fabric.charWidthsCache = { };
56226      }
56227      else if (fabric.charWidthsCache[fontFamily]) {
56228        delete fabric.charWidthsCache[fontFamily];
56229      }
56230    },
56231
56232    /**
56233     * Given current aspect ratio, determines the max width and height that can
56234     * respect the total allowed area for the cache.
56235     * @memberOf fabric.util
56236     * @param {Number} ar aspect ratio
56237     * @param {Number} maximumArea Maximum area you want to achieve
56238     * @return {Object.x} Limited dimensions by X
56239     * @return {Object.y} Limited dimensions by Y
56240     */
56241    limitDimsByArea: function(ar, maximumArea) {
56242      var roughWidth = Math.sqrt(maximumArea * ar),
56243          perfLimitSizeY = Math.floor(maximumArea / roughWidth);
56244      return { x: Math.floor(roughWidth), y: perfLimitSizeY };
56245    },
56246
56247    capValue: function(min, value, max) {
56248      return Math.max(min, Math.min(value, max));
56249    },
56250
56251    /**
56252     * Finds the scale for the object source to fit inside the object destination,
56253     * keeping aspect ratio intact.
56254     * respect the total allowed area for the cache.
56255     * @memberOf fabric.util
56256     * @param {Object | fabric.Object} source
56257     * @param {Number} source.height natural unscaled height of the object
56258     * @param {Number} source.width natural unscaled width of the object
56259     * @param {Object | fabric.Object} destination
56260     * @param {Number} destination.height natural unscaled height of the object
56261     * @param {Number} destination.width natural unscaled width of the object
56262     * @return {Number} scale factor to apply to source to fit into destination
56263     */
56264    findScaleToFit: function(source, destination) {
56265      return Math.min(destination.width / source.width, destination.height / source.height);
56266    },
56267
56268    /**
56269     * Finds the scale for the object source to cover entirely the object destination,
56270     * keeping aspect ratio intact.
56271     * respect the total allowed area for the cache.
56272     * @memberOf fabric.util
56273     * @param {Object | fabric.Object} source
56274     * @param {Number} source.height natural unscaled height of the object
56275     * @param {Number} source.width natural unscaled width of the object
56276     * @param {Object | fabric.Object} destination
56277     * @param {Number} destination.height natural unscaled height of the object
56278     * @param {Number} destination.width natural unscaled width of the object
56279     * @return {Number} scale factor to apply to source to cover destination
56280     */
56281    findScaleToCover: function(source, destination) {
56282      return Math.max(destination.width / source.width, destination.height / source.height);
56283    },
56284
56285    /**
56286     * given an array of 6 number returns something like `"matrix(...numbers)"`
56287     * @memberOf fabric.util
56288     * @param {Array} transform an array with 6 numbers
56289     * @return {String} transform matrix for svg
56290     * @return {Object.y} Limited dimensions by Y
56291     */
56292    matrixToSVG: function(transform) {
56293      return 'matrix(' + transform.map(function(value) {
56294        return fabric.util.toFixed(value, fabric.Object.NUM_FRACTION_DIGITS);
56295      }).join(' ') + ')';
56296    },
56297
56298    /**
56299     * given an object and a transform, apply the inverse transform to the object,
56300     * this is equivalent to remove from that object that transformation, so that
56301     * added in a space with the removed transform, the object will be the same as before.
56302     * Removing from an object a transform that scale by 2 is like scaling it by 1/2.
56303     * Removing from an object a transfrom that rotate by 30deg is like rotating by 30deg
56304     * in the opposite direction.
56305     * This util is used to add objects inside transformed groups or nested groups.
56306     * @memberOf fabric.util
56307     * @param {fabric.Object} object the object you want to transform
56308     * @param {Array} transform the destination transform
56309     */
56310    removeTransformFromObject: function(object, transform) {
56311      var inverted = fabric.util.invertTransform(transform),
56312          finalTransform = fabric.util.multiplyTransformMatrices(inverted, object.calcOwnMatrix());
56313      fabric.util.applyTransformToObject(object, finalTransform);
56314    },
56315
56316    /**
56317     * given an object and a transform, apply the transform to the object.
56318     * this is equivalent to change the space where the object is drawn.
56319     * Adding to an object a transform that scale by 2 is like scaling it by 2.
56320     * This is used when removing an object from an active selection for example.
56321     * @memberOf fabric.util
56322     * @param {fabric.Object} object the object you want to transform
56323     * @param {Array} transform the destination transform
56324     */
56325    addTransformToObject: function(object, transform) {
56326      fabric.util.applyTransformToObject(
56327        object,
56328        fabric.util.multiplyTransformMatrices(transform, object.calcOwnMatrix())
56329      );
56330    },
56331
56332    /**
56333     * discard an object transform state and apply the one from the matrix.
56334     * @memberOf fabric.util
56335     * @param {fabric.Object} object the object you want to transform
56336     * @param {Array} transform the destination transform
56337     */
56338    applyTransformToObject: function(object, transform) {
56339      var options = fabric.util.qrDecompose(transform),
56340          center = new fabric.Point(options.translateX, options.translateY);
56341      object.flipX = false;
56342      object.flipY = false;
56343      object.set('scaleX', options.scaleX);
56344      object.set('scaleY', options.scaleY);
56345      object.skewX = options.skewX;
56346      object.skewY = options.skewY;
56347      object.angle = options.angle;
56348      object.setPositionByOrigin(center, 'center', 'center');
56349    },
56350
56351    /**
56352     * given a width and height, return the size of the bounding box
56353     * that can contains the box with width/height with applied transform
56354     * described in options.
56355     * Use to calculate the boxes around objects for controls.
56356     * @memberOf fabric.util
56357     * @param {Number} width
56358     * @param {Number} height
56359     * @param {Object} options
56360     * @param {Number} options.scaleX
56361     * @param {Number} options.scaleY
56362     * @param {Number} options.skewX
56363     * @param {Number} options.skewY
56364     * @return {Object.x} width of containing
56365     * @return {Object.y} height of containing
56366     */
56367    sizeAfterTransform: function(width, height, options) {
56368      var dimX = width / 2, dimY = height / 2,
56369          points = [
56370            {
56371              x: -dimX,
56372              y: -dimY
56373            },
56374            {
56375              x: dimX,
56376              y: -dimY
56377            },
56378            {
56379              x: -dimX,
56380              y: dimY
56381            },
56382            {
56383              x: dimX,
56384              y: dimY
56385            }],
56386          transformMatrix = fabric.util.calcDimensionsMatrix(options),
56387          bbox = fabric.util.makeBoundingBoxFromPoints(points, transformMatrix);
56388      return {
56389        x: bbox.width,
56390        y: bbox.height,
56391      };
56392    }
56393  };
56394})( true ? exports : 
56394this
vendor: 106,699 bytes, lines 56394-59848
56394);
56395
56396
56397(function() {
56398  var _join = Array.prototype.join,
56399      commandLengths = {
56400        m: 2,
56401        l: 2,
56402        h: 1,
56403        v: 1,
56404        c: 6,
56405        s: 4,
56406        q: 4,
56407        t: 2,
56408        a: 7
56409      },
56410      repeatedCommands = {
56411        m: 'l',
56412        M: 'L'
56413      };
56414  function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) {
56415    var costh2 = fabric.util.cos(th2),
56416        sinth2 = fabric.util.sin(th2),
56417        costh3 = fabric.util.cos(th3),
56418        sinth3 = fabric.util.sin(th3),
56419        toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1,
56420        toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1,
56421        cp1X = fromX + mT * ( -cosTh * rx * sinth2 - sinTh * ry * costh2),
56422        cp1Y = fromY + mT * ( -sinTh * rx * sinth2 + cosTh * ry * costh2),
56423        cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3),
56424        cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3);
56425
56426    return ['C',
56427      cp1X, cp1Y,
56428      cp2X, cp2Y,
56429      toX, toY
56430    ];
56431  }
56432
56433  /* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp
56434   * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here
56435   * http://mozilla.org/MPL/2.0/
56436   */
56437  function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {
56438    var PI = Math.PI, th = rotateX * PI / 180,
56439        sinTh = fabric.util.sin(th),
56440        cosTh = fabric.util.cos(th),
56441        fromX = 0, fromY = 0;
56442
56443    rx = Math.abs(rx);
56444    ry = Math.abs(ry);
56445
56446    var px = -cosTh * toX * 0.5 - sinTh * toY * 0.5,
56447        py = -cosTh * toY * 0.5 + sinTh * toX * 0.5,
56448        rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px,
56449        pl = rx2 * ry2 - rx2 * py2 - ry2 * px2,
56450        root = 0;
56451
56452    if (pl < 0) {
56453      var s = Math.sqrt(1 - pl / (rx2 * ry2));
56454      rx *= s;
56455      ry *= s;
56456    }
56457    else {
56458      root = (large === sweep ? -1.0 : 1.0) *
56459              Math.sqrt( pl / (rx2 * py2 + ry2 * px2));
56460    }
56461
56462    var cx = root * rx * py / ry,
56463        cy = -root * ry * px / rx,
56464        cx1 = cosTh * cx - sinTh * cy + toX * 0.5,
56465        cy1 = sinTh * cx + cosTh * cy + toY * 0.5,
56466        mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry),
56467        dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry);
56468
56469    if (sweep === 0 && dtheta > 0) {
56470      dtheta -= 2 * PI;
56471    }
56472    else if (sweep === 1 && dtheta < 0) {
56473      dtheta += 2 * PI;
56474    }
56475
56476    // Convert into cubic bezier segments <= 90deg
56477    var segments = Math.ceil(Math.abs(dtheta / PI * 2)),
56478        result = [], mDelta = dtheta / segments,
56479        mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2),
56480        th3 = mTheta + mDelta;
56481
56482    for (var i = 0; i < segments; i++) {
56483      result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY);
56484      fromX = result[i][5];
56485      fromY = result[i][6];
56486      mTheta = th3;
56487      th3 += mDelta;
56488    }
56489    return result;
56490  }
56491
56492  /*
56493   * Private
56494   */
56495  function calcVectorAngle(ux, uy, vx, vy) {
56496    var ta = Math.atan2(uy, ux),
56497        tb = Math.atan2(vy, vx);
56498    if (tb >= ta) {
56499      return tb - ta;
56500    }
56501    else {
56502      return 2 * Math.PI - (ta - tb);
56503    }
56504  }
56505
56506  /**
56507   * Calculate bounding box of a beziercurve
56508   * @param {Number} x0 starting point
56509   * @param {Number} y0
56510   * @param {Number} x1 first control point
56511   * @param {Number} y1
56512   * @param {Number} x2 secondo control point
56513   * @param {Number} y2
56514   * @param {Number} x3 end of bezier
56515   * @param {Number} y3
56516   */
56517  // taken from http://jsbin.com/ivomiq/56/edit  no credits available for that.
56518  // TODO: can we normalize this with the starting points set at 0 and then translated the bbox?
56519  function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) {
56520    var argsString;
56521    if (fabric.cachesBoundsOfCurve) {
56522      argsString = _join.call(arguments);
56523      if (fabric.boundsOfCurveCache[argsString]) {
56524        return fabric.boundsOfCurveCache[argsString];
56525      }
56526    }
56527
56528    var sqrt = Math.sqrt,
56529        min = Math.min, max = Math.max,
56530        abs = Math.abs, tvalues = [],
56531        bounds = [[], []],
56532        a, b, c, t, t1, t2, b2ac, sqrtb2ac;
56533
56534    b = 6 * x0 - 12 * x1 + 6 * x2;
56535    a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;
56536    c = 3 * x1 - 3 * x0;
56537
56538    for (var i = 0; i < 2; ++i) {
56539      if (i > 0) {
56540        b = 6 * y0 - 12 * y1 + 6 * y2;
56541        a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;
56542        c = 3 * y1 - 3 * y0;
56543      }
56544
56545      if (abs(a) < 1e-12) {
56546        if (abs(b) < 1e-12) {
56547          continue;
56548        }
56549        t = -c / b;
56550        if (0 < t && t < 1) {
56551          tvalues.push(t);
56552        }
56553        continue;
56554      }
56555      b2ac = b * b - 4 * c * a;
56556      if (b2ac < 0) {
56557        continue;
56558      }
56559      sqrtb2ac = sqrt(b2ac);
56560      t1 = (-b + sqrtb2ac) / (2 * a);
56561      if (0 < t1 && t1 < 1) {
56562        tvalues.push(t1);
56563      }
56564      t2 = (-b - sqrtb2ac) / (2 * a);
56565      if (0 < t2 && t2 < 1) {
56566        tvalues.push(t2);
56567      }
56568    }
56569
56570    var x, y, j = tvalues.length, jlen = j, mt;
56571    while (j--) {
56572      t = tvalues[j];
56573      mt = 1 - t;
56574      x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);
56575      bounds[0][j] = x;
56576
56577      y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);
56578      bounds[1][j] = y;
56579    }
56580
56581    bounds[0][jlen] = x0;
56582    bounds[1][jlen] = y0;
56583    bounds[0][jlen + 1] = x3;
56584    bounds[1][jlen + 1] = y3;
56585    var result = [
56586      {
56587        x: min.apply(null, bounds[0]),
56588        y: min.apply(null, bounds[1])
56589      },
56590      {
56591        x: max.apply(null, bounds[0]),
56592        y: max.apply(null, bounds[1])
56593      }
56594    ];
56595    if (fabric.cachesBoundsOfCurve) {
56596      fabric.boundsOfCurveCache[argsString] = result;
56597    }
56598    return result;
56599  }
56600
56601  /**
56602   * Converts arc to a bunch of bezier curves
56603   * @param {Number} fx starting point x
56604   * @param {Number} fy starting point y
56605   * @param {Array} coords Arc command
56606   */
56607  function fromArcToBeziers(fx, fy, coords) {
56608    var rx = coords[1],
56609        ry = coords[2],
56610        rot = coords[3],
56611        large = coords[4],
56612        sweep = coords[5],
56613        tx = coords[6],
56614        ty = coords[7],
56615        segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);
56616
56617    for (var i = 0, len = segsNorm.length; i < len; i++) {
56618      segsNorm[i][1] += fx;
56619      segsNorm[i][2] += fy;
56620      segsNorm[i][3] += fx;
56621      segsNorm[i][4] += fy;
56622      segsNorm[i][5] += fx;
56623      segsNorm[i][6] += fy;
56624    }
56625    return segsNorm;
56626  };
56627
56628  /**
56629   * This function take a parsed SVG path and make it simpler for fabricJS logic.
56630   * simplification consist of: only UPPERCASE absolute commands ( relative converted to absolute )
56631   * S converted in C, T converted in Q, A converted in C.
56632   * @param {Array} path the array of commands of a parsed svg path for fabric.Path
56633   * @return {Array} the simplified array of commands of a parsed svg path for fabric.Path
56634   */
56635  function makePathSimpler(path) {
56636    // x and y represent the last point of the path. the previous command point.
56637    // we add them to each relative command to make it an absolute comment.
56638    // we also swap the v V h H with L, because are easier to transform.
56639    var x = 0, y = 0, len = path.length,
56640        // x1 and y1 represent the last point of the subpath. the subpath is started with
56641        // m or M command. When a z or Z command is drawn, x and y need to be resetted to
56642        // the last x1 and y1.
56643        x1 = 0, y1 = 0, current, i, converted,
56644        // previous will host the letter of the previous command, to handle S and T.
56645        // controlX and controlY will host the previous reflected control point
56646        destinationPath = [], previous, controlX, controlY;
56647    for (i = 0; i < len; ++i) {
56648      converted = false;
56649      current = path[i].slice(0);
56650      switch (current[0]) { // first letter
56651        case 'l': // lineto, relative
56652          current[0] = 'L';
56653          current[1] += x;
56654          current[2] += y;
56655          // falls through
56656        case 'L':
56657          x = current[1];
56658          y = current[2];
56659          break;
56660        case 'h': // horizontal lineto, relative
56661          current[1] += x;
56662          // falls through
56663        case 'H':
56664          current[0] = 'L';
56665          current[2] = y;
56666          x = current[1];
56667          break;
56668        case 'v': // vertical lineto, relative
56669          current[1] += y;
56670          // falls through
56671        case 'V':
56672          current[0] = 'L';
56673          y = current[1];
56674          current[1] = x;
56675          current[2] = y;
56676          break;
56677        case 'm': // moveTo, relative
56678          current[0] = 'M';
56679          current[1] += x;
56680          current[2] += y;
56681          // falls through
56682        case 'M':
56683          x = current[1];
56684          y = current[2];
56685          x1 = current[1];
56686          y1 = current[2];
56687          break;
56688        case 'c': // bezierCurveTo, relative
56689          current[0] = 'C';
56690          current[1] += x;
56691          current[2] += y;
56692          current[3] += x;
56693          current[4] += y;
56694          current[5] += x;
56695          current[6] += y;
56696          // falls through
56697        case 'C':
56698          controlX = current[3];
56699          controlY = current[4];
56700          x = current[5];
56701          y = current[6];
56702          break;
56703        case 's': // shorthand cubic bezierCurveTo, relative
56704          current[0] = 'S';
56705          current[1] += x;
56706          current[2] += y;
56707          current[3] += x;
56708          current[4] += y;
56709          // falls through
56710        case 'S':
56711          // would be sScC but since we are swapping sSc for C, we check just that.
56712          if (previous === 'C') {
56713            // calculate reflection of previous control points
56714            controlX = 2 * x - controlX;
56715            controlY = 2 * y - controlY;
56716          }
56717          else {
56718            // If there is no previous command or if the previous command was not a C, c, S, or s,
56719            // the control point is coincident with the current point
56720            controlX = x;
56721            controlY = y;
56722          }
56723          x = current[3];
56724          y = current[4];
56725          current[0] = 'C';
56726          current[5] = current[3];
56727          current[6] = current[4];
56728          current[3] = current[1];
56729          current[4] = current[2];
56730          current[1] = controlX;
56731          current[2] = controlY;
56732          // current[3] and current[4] are NOW the second control point.
56733          // we keep it for the next reflection.
56734          controlX = current[3];
56735          controlY = current[4];
56736          break;
56737        case 'q': // quadraticCurveTo, relative
56738          current[0] = 'Q';
56739          current[1] += x;
56740          current[2] += y;
56741          current[3] += x;
56742          current[4] += y;
56743          // falls through
56744        case 'Q':
56745          controlX = current[1];
56746          controlY = current[2];
56747          x = current[3];
56748          y = current[4];
56749          break;
56750        case 't': // shorthand quadraticCurveTo, relative
56751          current[0] = 'T';
56752          current[1] += x;
56753          current[2] += y;
56754          // falls through
56755        case 'T':
56756          if (previous === 'Q') {
56757            // calculate reflection of previous control point
56758            controlX = 2 * x - controlX;
56759            controlY = 2 * y - controlY;
56760          }
56761          else {
56762            // If there is no previous command or if the previous command was not a Q, q, T or t,
56763            // assume the control point is coincident with the current point
56764            controlX = x;
56765            controlY = y;
56766          }
56767          current[0] = 'Q';
56768          x = current[1];
56769          y = current[2];
56770          current[1] = controlX;
56771          current[2] = controlY;
56772          current[3] = x;
56773          current[4] = y;
56774          break;
56775        case 'a':
56776          current[0] = 'A';
56777          current[6] += x;
56778          current[7] += y;
56779          // falls through
56780        case 'A':
56781          converted = true;
56782          destinationPath = destinationPath.concat(fromArcToBeziers(x, y, current));
56783          x = current[6];
56784          y = current[7];
56785          break;
56786        case 'z':
56787        case 'Z':
56788          x = x1;
56789          y = y1;
56790          break;
56791        default:
56792      }
56793      if (!converted) {
56794        destinationPath.push(current);
56795      }
56796      previous = current[0];
56797    }
56798    return destinationPath;
56799  };
56800
56801  /**
56802   * Calc length from point x1,y1 to x2,y2
56803   * @param {Number} x1 starting point x
56804   * @param {Number} y1 starting point y
56805   * @param {Number} x2 starting point x
56806   * @param {Number} y2 starting point y
56807   * @return {Number} length of segment
56808   */
56809  function calcLineLength(x1, y1, x2, y2) {
56810    return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
56811  }
56812
56813  // functions for the Cubic beizer
56814  // taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350
56815  function CB1(t) {
56816    return t * t * t;
56817  }
56818  function CB2(t) {
56819    return 3 * t * t * (1 - t);
56820  }
56821  function CB3(t) {
56822    return 3 * t * (1 - t) * (1 - t);
56823  }
56824  function CB4(t) {
56825    return (1 - t) * (1 - t) * (1 - t);
56826  }
56827
56828  function getPointOnCubicBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) {
56829    return function(pct) {
56830      var c1 = CB1(pct), c2 = CB2(pct), c3 = CB3(pct), c4 = CB4(pct);
56831      return {
56832        x: p4x * c1 + p3x * c2 + p2x * c3 + p1x * c4,
56833        y: p4y * c1 + p3y * c2 + p2y * c3 + p1y * c4
56834      };
56835    };
56836  }
56837
56838  function getTangentCubicIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) {
56839    return function (pct) {
56840      var invT = 1 - pct,
56841          tangentX = (3 * invT * invT * (p2x - p1x)) + (6 * invT * pct * (p3x - p2x)) +
56842          (3 * pct * pct * (p4x - p3x)),
56843          tangentY = (3 * invT * invT * (p2y - p1y)) + (6 * invT * pct * (p3y - p2y)) +
56844          (3 * pct * pct * (p4y - p3y));
56845      return Math.atan2(tangentY, tangentX);
56846    };
56847  }
56848
56849  function QB1(t) {
56850    return t * t;
56851  }
56852
56853  function QB2(t) {
56854    return 2 * t * (1 - t);
56855  }
56856
56857  function QB3(t) {
56858    return (1 - t) * (1 - t);
56859  }
56860
56861  function getPointOnQuadraticBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y) {
56862    return function(pct) {
56863      var c1 = QB1(pct), c2 = QB2(pct), c3 = QB3(pct);
56864      return {
56865        x: p3x * c1 + p2x * c2 + p1x * c3,
56866        y: p3y * c1 + p2y * c2 + p1y * c3
56867      };
56868    };
56869  }
56870
56871  function getTangentQuadraticIterator(p1x, p1y, p2x, p2y, p3x, p3y) {
56872    return function (pct) {
56873      var invT = 1 - pct,
56874          tangentX = (2 * invT * (p2x - p1x)) + (2 * pct * (p3x - p2x)),
56875          tangentY = (2 * invT * (p2y - p1y)) + (2 * pct * (p3y - p2y));
56876      return Math.atan2(tangentY, tangentX);
56877    };
56878  }
56879
56880
56881  // this will run over a path segment ( a cubic or quadratic segment) and approximate it
56882  // with 100 segemnts. This will good enough to calculate the length of the curve
56883  function pathIterator(iterator, x1, y1) {
56884    var tempP = { x: x1, y: y1 }, p, tmpLen = 0, perc;
56885    for (perc = 1; perc <= 100; perc += 1) {
56886      p = iterator(perc / 100);
56887      tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y);
56888      tempP = p;
56889    }
56890    return tmpLen;
56891  }
56892
56893  /**
56894   * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1
56895   * that correspond to that pixels run over the path.
56896   * The percentage will be then used to find the correct point on the canvas for the path.
56897   * @param {Array} segInfo fabricJS collection of information on a parsed path
56898   * @param {Number} distance from starting point, in pixels.
56899   * @return {Object} info object with x and y ( the point on canvas ) and angle, the tangent on that point;
56900   */
56901  function findPercentageForDistance(segInfo, distance) {
56902    var perc = 0, tmpLen = 0, iterator = segInfo.iterator, tempP = { x: segInfo.x, y: segInfo.y },
56903        p, nextLen, nextStep = 0.01, angleFinder = segInfo.angleFinder, lastPerc;
56904    // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100
56905    // the path
56906    while (tmpLen < distance && perc <= 1 && nextStep > 0.0001) {
56907      p = iterator(perc);
56908      lastPerc = perc;
56909      nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y);
56910      // compare tmpLen each cycle with distance, decide next perc to test.
56911      if ((nextLen + tmpLen) > distance) {
56912        // we discard this step and we make smaller steps.
56913        nextStep /= 2;
56914        perc -= nextStep;
56915      }
56916      else {
56917        tempP = p;
56918        perc += nextStep;
56919        tmpLen += nextLen;
56920      }
56921    }
56922    p.angle = angleFinder(lastPerc);
56923    return p;
56924  }
56925
56926  /**
56927   * Run over a parsed and simplifed path and extrac some informations.
56928   * informations are length of each command and starting point
56929   * @param {Array} path fabricJS parsed path commands
56930   * @return {Array} path commands informations
56931   */
56932  function getPathSegmentsInfo(path) {
56933    var totalLength = 0, len = path.length, current,
56934        //x2 and y2 are the coords of segment start
56935        //x1 and y1 are the coords of the current point
56936        x1 = 0, y1 = 0, x2 = 0, y2 = 0, info = [], iterator, tempInfo, angleFinder;
56937    for (var i = 0; i < len; i++) {
56938      current = path[i];
56939      tempInfo = {
56940        x: x1,
56941        y: y1,
56942        command: current[0],
56943      };
56944      switch (current[0]) { //first letter
56945        case 'M':
56946          tempInfo.length = 0;
56947          x2 = x1 = current[1];
56948          y2 = y1 = current[2];
56949          break;
56950        case 'L':
56951          tempInfo.length = calcLineLength(x1, y1, current[1], current[2]);
56952          x1 = current[1];
56953          y1 = current[2];
56954          break;
56955        case 'C':
56956          iterator = getPointOnCubicBezierIterator(
56957            x1,
56958            y1,
56959            current[1],
56960            current[2],
56961            current[3],
56962            current[4],
56963            current[5],
56964            current[6]
56965          );
56966          angleFinder = getTangentCubicIterator(
56967            x1,
56968            y1,
56969            current[1],
56970            current[2],
56971            current[3],
56972            current[4],
56973            current[5],
56974            current[6]
56975          );
56976          tempInfo.iterator = iterator;
56977          tempInfo.angleFinder = angleFinder;
56978          tempInfo.length = pathIterator(iterator, x1, y1);
56979          x1 = current[5];
56980          y1 = current[6];
56981          break;
56982        case 'Q':
56983          iterator = getPointOnQuadraticBezierIterator(
56984            x1,
56985            y1,
56986            current[1],
56987            current[2],
56988            current[3],
56989            current[4]
56990          );
56991          angleFinder = getTangentQuadraticIterator(
56992            x1,
56993            y1,
56994            current[1],
56995            current[2],
56996            current[3],
56997            current[4]
56998          );
56999          tempInfo.iterator = iterator;
57000          tempInfo.angleFinder = angleFinder;
57001          tempInfo.length = pathIterator(iterator, x1, y1);
57002          x1 = current[3];
57003          y1 = current[4];
57004          break;
57005        case 'Z':
57006        case 'z':
57007          // we add those in order to ease calculations later
57008          tempInfo.destX = x2;
57009          tempInfo.destY = y2;
57010          tempInfo.length = calcLineLength(x1, y1, x2, y2);
57011          x1 = x2;
57012          y1 = y2;
57013          break;
57014      }
57015      totalLength += tempInfo.length;
57016      info.push(tempInfo);
57017    }
57018    info.push({ length: totalLength, x: x1, y: y1 });
57019    return info;
57020  }
57021
57022  function getPointOnPath(path, distance, infos) {
57023    if (!infos) {
57024      infos = getPathSegmentsInfo(path);
57025    }
57026    var i = 0;
57027    while ((distance - infos[i].length > 0) && i < (infos.length - 2)) {
57028      distance -= infos[i].length;
57029      i++;
57030    }
57031    // var distance = infos[infos.length - 1] * perc;
57032    var segInfo = infos[i], segPercent = distance / segInfo.length,
57033        command = segInfo.command, segment = path[i], info;
57034
57035    switch (command) {
57036      case 'M':
57037        return { x: segInfo.x, y: segInfo.y, angle: 0 };
57038      case 'Z':
57039      case 'z':
57040        info = new fabric.Point(segInfo.x, segInfo.y).lerp(
57041          new fabric.Point(segInfo.destX, segInfo.destY),
57042          segPercent
57043        );
57044        info.angle = Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x);
57045        return info;
57046      case 'L':
57047        info = new fabric.Point(segInfo.x, segInfo.y).lerp(
57048          new fabric.Point(segment[1], segment[2]),
57049          segPercent
57050        );
57051        info.angle = Math.atan2(segment[2] - segInfo.y, segment[1] - segInfo.x);
57052        return info;
57053      case 'C':
57054        return findPercentageForDistance(segInfo, distance);
57055      case 'Q':
57056        return findPercentageForDistance(segInfo, distance);
57057    }
57058  }
57059
57060  /**
57061   *
57062   * @param {string} pathString
57063   * @return {(string|number)[][]} An array of SVG path commands
57064   * @example <caption>Usage</caption>
57065   * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [
57066   *   ['M', 3, 4],
57067   *   ['Q', 3, 5, 2, 1, 4, 0],
57068   *   ['Q', 9, 12, 2, 1, 4, 0],
57069   * ];
57070   *
57071   */
57072  function parsePath(pathString) {
57073    var result = [],
57074        coords = [],
57075        currentPath,
57076        parsed,
57077        re = fabric.rePathCommand,
57078        rNumber = '[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?\\s*',
57079        rNumberCommaWsp = '(' + rNumber + ')' + fabric.commaWsp,
57080        rFlagCommaWsp = '([01])' + fabric.commaWsp + '?',
57081        rArcSeq = rNumberCommaWsp + '?' + rNumberCommaWsp + '?' + rNumberCommaWsp + rFlagCommaWsp + rFlagCommaWsp +
57082          rNumberCommaWsp + '?(' + rNumber + ')',
57083        regArcArgumentSequence = new RegExp(rArcSeq, 'g'),
57084        match,
57085        coordsStr,
57086        // one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values)
57087        path;
57088    if (!pathString || !pathString.match) {
57089      return result;
57090    }
57091    path = pathString.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);
57092
57093    for (var i = 0, coordsParsed, len = path.length; i < len; i++) {
57094      currentPath = path[i];
57095
57096      coordsStr = currentPath.slice(1).trim();
57097      coords.length = 0;
57098
57099      var command = currentPath.charAt(0);
57100      coordsParsed = [command];
57101
57102      if (command.toLowerCase() === 'a') {
57103        // arcs have special flags that apparently don't require spaces so handle special
57104        for (var args; (args = regArcArgumentSequence.exec(coordsStr));) {
57105          for (var j = 1; j < args.length; j++) {
57106            coords.push(args[j]);
57107          }
57108        }
57109      }
57110      else {
57111        while ((match = re.exec(coordsStr))) {
57112          coords.push(match[0]);
57113        }
57114      }
57115
57116      for (var j = 0, jlen = coords.length; j < jlen; j++) {
57117        parsed = parseFloat(coords[j]);
57118        if (!isNaN(parsed)) {
57119          coordsParsed.push(parsed);
57120        }
57121      }
57122
57123      var commandLength = commandLengths[command.toLowerCase()],
57124          repeatedCommand = repeatedCommands[command] || command;
57125
57126      if (coordsParsed.length - 1 > commandLength) {
57127        for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) {
57128          result.push([command].concat(coordsParsed.slice(k, k + commandLength)));
57129          command = repeatedCommand;
57130        }
57131      }
57132      else {
57133        result.push(coordsParsed);
57134      }
57135    }
57136
57137    return result;
57138  };
57139
57140  /**
57141   *
57142   * Converts points to a smooth SVG path
57143   * @param {{ x: number,y: number }[]} points Array of points
57144   * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value.
57145   * @return {(string|number)[][]} An array of SVG path commands
57146   */
57147  function getSmoothPathFromPoints(points, correction) {
57148    var path = [], i,
57149        p1 = new fabric.Point(points[0].x, points[0].y),
57150        p2 = new fabric.Point(points[1].x, points[1].y),
57151        len = points.length, multSignX = 1, multSignY = 0, manyPoints = len > 2;
57152    correction = correction || 0;
57153
57154    if (manyPoints) {
57155      multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;
57156      multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;
57157    }
57158    path.push(['M', p1.x - multSignX * correction, p1.y - multSignY * correction]);
57159    for (i = 1; i < len; i++) {
57160      if (!p1.eq(p2)) {
57161        var midPoint = p1.midPointFrom(p2);
57162        // p1 is our bezier control point
57163        // midpoint is our endpoint
57164        // start point is p(i-1) value.
57165        path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]);
57166      }
57167      p1 = points[i];
57168      if ((i + 1) < points.length) {
57169        p2 = points[i + 1];
57170      }
57171    }
57172    if (manyPoints) {
57173      multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;
57174      multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;
57175    }
57176    path.push(['L', p1.x + multSignX * correction, p1.y + multSignY * correction]);
57177    return path;
57178  }
57179  /**
57180   * Transform a path by transforming each segment.
57181   * it has to be a simplified path or it won't work.
57182   * WARNING: this depends from pathOffset for correct operation
57183   * @param {Array} path fabricJS parsed and simplified path commands
57184   * @param {Array} transform matrix that represent the transformation
57185   * @param {Object} [pathOffset] the fabric.Path pathOffset
57186   * @param {Number} pathOffset.x
57187   * @param {Number} pathOffset.y
57188   * @returns {Array} the transformed path
57189   */
57190  function transformPath(path, transform, pathOffset) {
57191    if (pathOffset) {
57192      transform = fabric.util.multiplyTransformMatrices(
57193        transform,
57194        [1, 0, 0, 1, -pathOffset.x, -pathOffset.y]
57195      );
57196    }
57197    return path.map(function(pathSegment) {
57198      var newSegment = pathSegment.slice(0), point = {};
57199      for (var i = 1; i < pathSegment.length - 1; i += 2) {
57200        point.x = pathSegment[i];
57201        point.y = pathSegment[i + 1];
57202        point = fabric.util.transformPoint(point, transform);
57203        newSegment[i] = point.x;
57204        newSegment[i + 1] = point.y;
57205      }
57206      return newSegment;
57207    });
57208  }
57209
57210  /**
57211   * Calculate bounding box of a elliptic-arc
57212   * @deprecated
57213   * @param {Number} fx start point of arc
57214   * @param {Number} fy
57215   * @param {Number} rx horizontal radius
57216   * @param {Number} ry vertical radius
57217   * @param {Number} rot angle of horizontal axis
57218   * @param {Number} large 1 or 0, whatever the arc is the big or the small on the 2 points
57219   * @param {Number} sweep 1 or 0, 1 clockwise or counterclockwise direction
57220   * @param {Number} tx end point of arc
57221   * @param {Number} ty
57222   */
57223  function getBoundsOfArc(fx, fy, rx, ry, rot, large, sweep, tx, ty) {
57224
57225    var fromX = 0, fromY = 0, bound, bounds = [],
57226        segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);
57227
57228    for (var i = 0, len = segs.length; i < len; i++) {
57229      bound = getBoundsOfCurve(fromX, fromY, segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5], segs[i][6]);
57230      bounds.push({ x: bound[0].x + fx, y: bound[0].y + fy });
57231      bounds.push({ x: bound[1].x + fx, y: bound[1].y + fy });
57232      fromX = segs[i][5];
57233      fromY = segs[i][6];
57234    }
57235    return bounds;
57236  };
57237
57238  /**
57239   * Draws arc
57240   * @deprecated
57241   * @param {CanvasRenderingContext2D} ctx
57242   * @param {Number} fx
57243   * @param {Number} fy
57244   * @param {Array} coords coords of the arc, without the front 'A/a'
57245   */
57246  function drawArc(ctx, fx, fy, coords) {
57247    coords = coords.slice(0).unshift('X'); // command A or a does not matter
57248    var beziers = fromArcToBeziers(fx, fy, coords);
57249    beziers.forEach(function(bezier) {
57250      ctx.bezierCurveTo.apply(ctx, bezier.slice(1));
57251    });
57252  };
57253
57254  /**
57255   * Join path commands to go back to svg format
57256   * @param {Array} pathData fabricJS parsed path commands
57257   * @return {String} joined path 'M 0 0 L 20 30'
57258   */
57259  fabric.util.joinPath = function(pathData) {
57260    return pathData.map(function (segment) { return segment.join(' '); }).join(' ');
57261  };
57262  fabric.util.parsePath = parsePath;
57263  fabric.util.makePathSimpler = makePathSimpler;
57264  fabric.util.getSmoothPathFromPoints = getSmoothPathFromPoints;
57265  fabric.util.getPathSegmentsInfo = getPathSegmentsInfo;
57266  fabric.util.getBoundsOfCurve = getBoundsOfCurve;
57267  fabric.util.getPointOnPath = getPointOnPath;
57268  fabric.util.transformPath = transformPath;
57269  /**
57270   * Typo of `fromArcToBeziers` kept for not breaking the api once corrected.
57271   * Will be removed in fabric 5.0
57272   * @deprecated
57273   */
57274  fabric.util.fromArcToBeizers = fromArcToBeziers;
57275  // kept because we do not want to make breaking changes.
57276  // but useless and deprecated.
57277  fabric.util.getBoundsOfArc = getBoundsOfArc;
57278  fabric.util.drawArc = drawArc;
57279})();
57280
57281
57282(function() {
57283
57284  var slice = Array.prototype.slice;
57285
57286  /**
57287   * Invokes method on all items in a given array
57288   * @memberOf fabric.util.array
57289   * @param {Array} array Array to iterate over
57290   * @param {String} method Name of a method to invoke
57291   * @return {Array}
57292   */
57293  function invoke(array, method) {
57294    var args = slice.call(arguments, 2), result = [];
57295    for (var i = 0, len = array.length; i < len; i++) {
57296      result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]);
57297    }
57298    return result;
57299  }
57300
57301  /**
57302   * Finds maximum value in array (not necessarily "first" one)
57303   * @memberOf fabric.util.array
57304   * @param {Array} array Array to iterate over
57305   * @param {String} byProperty
57306   * @return {*}
57307   */
57308  function max(array, byProperty) {
57309    return find(array, byProperty, function(value1, value2) {
57310      return value1 >= value2;
57311    });
57312  }
57313
57314  /**
57315   * Finds minimum value in array (not necessarily "first" one)
57316   * @memberOf fabric.util.array
57317   * @param {Array} array Array to iterate over
57318   * @param {String} byProperty
57319   * @return {*}
57320   */
57321  function min(array, byProperty) {
57322    return find(array, byProperty, function(value1, value2) {
57323      return value1 < value2;
57324    });
57325  }
57326
57327  /**
57328   * @private
57329   */
57330  function fill(array, value) {
57331    var k = array.length;
57332    while (k--) {
57333      array[k] = value;
57334    }
57335    return array;
57336  }
57337
57338  /**
57339   * @private
57340   */
57341  function find(array, byProperty, condition) {
57342    if (!array || array.length === 0) {
57343      return;
57344    }
57345
57346    var i = array.length - 1,
57347        result = byProperty ? array[i][byProperty] : array[i];
57348    if (byProperty) {
57349      while (i--) {
57350        if (condition(array[i][byProperty], result)) {
57351          result = array[i][byProperty];
57352        }
57353      }
57354    }
57355    else {
57356      while (i--) {
57357        if (condition(array[i], result)) {
57358          result = array[i];
57359        }
57360      }
57361    }
57362    return result;
57363  }
57364
57365  /**
57366   * @namespace fabric.util.array
57367   */
57368  fabric.util.array = {
57369    fill: fill,
57370    invoke: invoke,
57371    min: min,
57372    max: max
57373  };
57374
57375})();
57376
57377
57378(function() {
57379  /**
57380   * Copies all enumerable properties of one js object to another
57381   * this does not and cannot compete with generic utils.
57382   * Does not clone or extend fabric.Object subclasses.
57383   * This is mostly for internal use and has extra handling for fabricJS objects
57384   * it skips the canvas and group properties in deep cloning.
57385   * @memberOf fabric.util.object
57386   * @param {Object} destination Where to copy to
57387   * @param {Object} source Where to copy from
57388   * @param {Boolean} [deep] Whether to extend nested objects
57389   * @return {Object}
57390   */
57391
57392  function extend(destination, source, deep) {
57393    // JScript DontEnum bug is not taken care of
57394    // the deep clone is for internal use, is not meant to avoid
57395    // javascript traps or cloning html element or self referenced objects.
57396    if (deep) {
57397      if (!fabric.isLikelyNode && source instanceof Element) {
57398        // avoid cloning deep images, canvases,
57399        destination = source;
57400      }
57401      else if (source instanceof Array) {
57402        destination = [];
57403        for (var i = 0, len = source.length; i < len; i++) {
57404          destination[i] = extend({ }, source[i], deep);
57405        }
57406      }
57407      else if (source && typeof source === 'object') {
57408        for (var property in source) {
57409          if (property === 'canvas' || property === 'group') {
57410            // we do not want to clone this props at all.
57411            // we want to keep the keys in the copy
57412            destination[property] = null;
57413          }
57414          else if (source.hasOwnProperty(property)) {
57415            destination[property] = extend({ }, source[property], deep);
57416          }
57417        }
57418      }
57419      else {
57420        // this sounds odd for an extend but is ok for recursive use
57421        destination = source;
57422      }
57423    }
57424    else {
57425      for (var property in source) {
57426        destination[property] = source[property];
57427      }
57428    }
57429    return destination;
57430  }
57431
57432  /**
57433   * Creates an empty object and copies all enumerable properties of another object to it
57434   * This method is mostly for internal use, and not intended for duplicating shapes in canvas.
57435   * @memberOf fabric.util.object
57436   * @param {Object} object Object to clone
57437   * @param {Boolean} [deep] Whether to clone nested objects
57438   * @return {Object}
57439   */
57440
57441  //TODO: this function return an empty object if you try to clone null
57442  function clone(object, deep) {
57443    return extend({ }, object, deep);
57444  }
57445
57446  /** @namespace fabric.util.object */
57447  fabric.util.object = {
57448    extend: extend,
57449    clone: clone
57450  };
57451  fabric.util.object.extend(fabric.util, fabric.Observable);
57452})();
57453
57454
57455(function() {
57456
57457  /**
57458   * Camelizes a string
57459   * @memberOf fabric.util.string
57460   * @param {String} string String to camelize
57461   * @return {String} Camelized version of a string
57462   */
57463  function camelize(string) {
57464    return string.replace(/-+(.)?/g, function(match, character) {
57465      return character ? character.toUpperCase() : '';
57466    });
57467  }
57468
57469  /**
57470   * Capitalizes a string
57471   * @memberOf fabric.util.string
57472   * @param {String} string String to capitalize
57473   * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized
57474   * and other letters stay untouched, if false first letter is capitalized
57475   * and other letters are converted to lowercase.
57476   * @return {String} Capitalized version of a string
57477   */
57478  function capitalize(string, firstLetterOnly) {
57479    return string.charAt(0).toUpperCase() +
57480      (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase());
57481  }
57482
57483  /**
57484   * Escapes XML in a string
57485   * @memberOf fabric.util.string
57486   * @param {String} string String to escape
57487   * @return {String} Escaped version of a string
57488   */
57489  function escapeXml(string) {
57490    return string.replace(/&/g, '&amp;')
57491      .replace(/"/g, '&quot;')
57492      .replace(/'/g, '&apos;')
57493      .replace(/</g, '&lt;')
57494      .replace(/>/g, '&gt;');
57495  }
57496
57497  /**
57498   * Divide a string in the user perceived single units
57499   * @memberOf fabric.util.string
57500   * @param {String} textstring String to escape
57501   * @return {Array} array containing the graphemes
57502   */
57503  function graphemeSplit(textstring) {
57504    var i = 0, chr, graphemes = [];
57505    for (i = 0, chr; i < textstring.length; i++) {
57506      if ((chr = getWholeChar(textstring, i)) === false) {
57507        continue;
57508      }
57509      graphemes.push(chr);
57510    }
57511    return graphemes;
57512  }
57513
57514  // taken from mdn in the charAt doc page.
57515  function getWholeChar(str, i) {
57516    var code = str.charCodeAt(i);
57517
57518    if (isNaN(code)) {
57519      return ''; // Position not found
57520    }
57521    if (code < 0xD800 || code > 0xDFFF) {
57522      return str.charAt(i);
57523    }
57524
57525    // High surrogate (could change last hex to 0xDB7F to treat high private
57526    // surrogates as single characters)
57527    if (0xD800 <= code && code <= 0xDBFF) {
57528      if (str.length <= (i + 1)) {
57529        throw 'High surrogate without following low surrogate';
57530      }
57531      var next = str.charCodeAt(i + 1);
57532      if (0xDC00 > next || next > 0xDFFF) {
57533        throw 'High surrogate without following low surrogate';
57534      }
57535      return str.charAt(i) + str.charAt(i + 1);
57536    }
57537    // Low surrogate (0xDC00 <= code && code <= 0xDFFF)
57538    if (i === 0) {
57539      throw 'Low surrogate without preceding high surrogate';
57540    }
57541    var prev = str.charCodeAt(i - 1);
57542
57543    // (could change last hex to 0xDB7F to treat high private
57544    // surrogates as single characters)
57545    if (0xD800 > prev || prev > 0xDBFF) {
57546      throw 'Low surrogate without preceding high surrogate';
57547    }
57548    // We can pass over low surrogates now as the second component
57549    // in a pair which we have already processed
57550    return false;
57551  }
57552
57553
57554  /**
57555   * String utilities
57556   * @namespace fabric.util.string
57557   */
57558  fabric.util.string = {
57559    camelize: camelize,
57560    capitalize: capitalize,
57561    escapeXml: escapeXml,
57562    graphemeSplit: graphemeSplit
57563  };
57564})();
57565
57566
57567(function() {
57568
57569  var slice = Array.prototype.slice, emptyFunction = function() { },
57570
57571      IS_DONTENUM_BUGGY = (function() {
57572        for (var p in { toString: 1 }) {
57573          if (p === 'toString') {
57574            return false;
57575          }
57576        }
57577        return true;
57578      })(),
57579
57580      /** @ignore */
57581      addMethods = function(klass, source, parent) {
57582        for (var property in source) {
57583
57584          if (property in klass.prototype &&
57585              typeof klass.prototype[property] === 'function' &&
57586              (source[property] + '').indexOf('callSuper') > -1) {
57587
57588            klass.prototype[property] = (function(property) {
57589              return function() {
57590
57591                var superclass = this.constructor.superclass;
57592                this.constructor.superclass = parent;
57593                var returnValue = source[property].apply(this, arguments);
57594                this.constructor.superclass = superclass;
57595
57596                if (property !== 'initialize') {
57597                  return returnValue;
57598                }
57599              };
57600            })(property);
57601          }
57602          else {
57603            klass.prototype[property] = source[property];
57604          }
57605
57606          if (IS_DONTENUM_BUGGY) {
57607            if (source.toString !== Object.prototype.toString) {
57608              klass.prototype.toString = source.toString;
57609            }
57610            if (source.valueOf !== Object.prototype.valueOf) {
57611              klass.prototype.valueOf = source.valueOf;
57612            }
57613          }
57614        }
57615      };
57616
57617  function Subclass() { }
57618
57619  function callSuper(methodName) {
57620    var parentMethod = null,
57621        _this = this;
57622
57623    // climb prototype chain to find method not equal to callee's method
57624    while (_this.constructor.superclass) {
57625      var superClassMethod = _this.constructor.superclass.prototype[methodName];
57626      if (_this[methodName] !== superClassMethod) {
57627        parentMethod = superClassMethod;
57628        break;
57629      }
57630      // eslint-disable-next-line
57631      _this = _this.constructor.superclass.prototype;
57632    }
57633
57634    if (!parentMethod) {
57635      return console.log('tried to callSuper ' + methodName + ', method not found in prototype chain', this);
57636    }
57637
57638    return (arguments.length > 1)
57639      ? parentMethod.apply(this, slice.call(arguments, 1))
57640      : parentMethod.call(this);
57641  }
57642
57643  /**
57644   * Helper for creation of "classes".
57645   * @memberOf fabric.util
57646   * @param {Function} [parent] optional "Class" to inherit from
57647   * @param {Object} [properties] Properties shared by all instances of this class
57648   *                  (be careful modifying objects defined here as this would affect all instances)
57649   */
57650  function createClass() {
57651    var parent = null,
57652        properties = slice.call(arguments, 0);
57653
57654    if (typeof properties[0] === 'function') {
57655      parent = properties.shift();
57656    }
57657    function klass() {
57658      this.initialize.apply(this, arguments);
57659    }
57660
57661    klass.superclass = parent;
57662    klass.subclasses = [];
57663
57664    if (parent) {
57665      Subclass.prototype = parent.prototype;
57666      klass.prototype = new Subclass();
57667      parent.subclasses.push(klass);
57668    }
57669    for (var i = 0, length = properties.length; i < length; i++) {
57670      addMethods(klass, properties[i], parent);
57671    }
57672    if (!klass.prototype.initialize) {
57673      klass.prototype.initialize = emptyFunction;
57674    }
57675    klass.prototype.constructor = klass;
57676    klass.prototype.callSuper = callSuper;
57677    return klass;
57678  }
57679
57680  fabric.util.createClass = createClass;
57681})();
57682
57683
57684(function () {
57685  // since ie11 can use addEventListener but they do not support options, i need to check
57686  var couldUseAttachEvent = !!fabric.document.createElement('div').attachEvent,
57687      touchEvents = ['touchstart', 'touchmove', 'touchend'];
57688  /**
57689   * Adds an event listener to an element
57690   * @function
57691   * @memberOf fabric.util
57692   * @param {HTMLElement} element
57693   * @param {String} eventName
57694   * @param {Function} handler
57695   */
57696  fabric.util.addListener = function(element, eventName, handler, options) {
57697    element && element.addEventListener(eventName, handler, couldUseAttachEvent ? false : options);
57698  };
57699
57700  /**
57701   * Removes an event listener from an element
57702   * @function
57703   * @memberOf fabric.util
57704   * @param {HTMLElement} element
57705   * @param {String} eventName
57706   * @param {Function} handler
57707   */
57708  fabric.util.removeListener = function(element, eventName, handler, options) {
57709    element && element.removeEventListener(eventName, handler, couldUseAttachEvent ? false : options);
57710  };
57711
57712  function getTouchInfo(event) {
57713    var touchProp = event.changedTouches;
57714    if (touchProp && touchProp[0]) {
57715      return touchProp[0];
57716    }
57717    return event;
57718  }
57719
57720  fabric.util.getPointer = function(event) {
57721    var element = event.target,
57722        scroll = fabric.util.getScrollLeftTop(element),
57723        _evt = getTouchInfo(event);
57724    return {
57725      x: _evt.clientX + scroll.left,
57726      y: _evt.clientY + scroll.top
57727    };
57728  };
57729
57730  fabric.util.isTouchEvent = function(event) {
57731    return touchEvents.indexOf(event.type) > -1 || event.pointerType === 'touch';
57732  };
57733})();
57734
57735
57736(function () {
57737
57738  /**
57739   * Cross-browser wrapper for setting element's style
57740   * @memberOf fabric.util
57741   * @param {HTMLElement} element
57742   * @param {Object} styles
57743   * @return {HTMLElement} Element that was passed as a first argument
57744   */
57745  function setStyle(element, styles) {
57746    var elementStyle = element.style;
57747    if (!elementStyle) {
57748      return element;
57749    }
57750    if (typeof styles === 'string') {
57751      element.style.cssText += ';' + styles;
57752      return styles.indexOf('opacity') > -1
57753        ? setOpacity(element, styles.match(/opacity:\s*(\d?\.?\d*)/)[1])
57754        : element;
57755    }
57756    for (var property in styles) {
57757      if (property === 'opacity') {
57758        setOpacity(element, styles[property]);
57759      }
57760      else {
57761        var normalizedProperty = (property === 'float' || property === 'cssFloat')
57762          ? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat')
57763          : property;
57764        elementStyle[normalizedProperty] = styles[property];
57765      }
57766    }
57767    return element;
57768  }
57769
57770  var parseEl = fabric.document.createElement('div'),
57771      supportsOpacity = typeof parseEl.style.opacity === 'string',
57772      supportsFilters = typeof parseEl.style.filter === 'string',
57773      reOpacity = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,
57774
57775      /** @ignore */
57776      setOpacity = function (element) { return element; };
57777
57778  if (supportsOpacity) {
57779    /** @ignore */
57780    setOpacity = function(element, value) {
57781      element.style.opacity = value;
57782      return element;
57783    };
57784  }
57785  else if (supportsFilters) {
57786    /** @ignore */
57787    setOpacity = function(element, value) {
57788      var es = element.style;
57789      if (element.currentStyle && !element.currentStyle.hasLayout) {
57790        es.zoom = 1;
57791      }
57792      if (reOpacity.test(es.filter)) {
57793        value = value >= 0.9999 ? '' : ('alpha(opacity=' + (value * 100) + ')');
57794        es.filter = es.filter.replace(reOpacity, value);
57795      }
57796      else {
57797        es.filter += ' alpha(opacity=' + (value * 100) + ')';
57798      }
57799      return element;
57800    };
57801  }
57802
57803  fabric.util.setStyle = setStyle;
57804
57805})();
57806
57807
57808(function() {
57809
57810  var _slice = Array.prototype.slice;
57811
57812  /**
57813   * Takes id and returns an element with that id (if one exists in a document)
57814   * @memberOf fabric.util
57815   * @param {String|HTMLElement} id
57816   * @return {HTMLElement|null}
57817   */
57818  function getById(id) {
57819    return typeof id === 'string' ? fabric.document.getElementById(id) : id;
57820  }
57821
57822  var sliceCanConvertNodelists,
57823      /**
57824       * Converts an array-like object (e.g. arguments or NodeList) to an array
57825       * @memberOf fabric.util
57826       * @param {Object} arrayLike
57827       * @return {Array}
57828       */
57829      toArray = function(arrayLike) {
57830        return _slice.call(arrayLike, 0);
57831      };
57832
57833  try {
57834    sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array;
57835  }
57836  catch (err) { }
57837
57838  if (!sliceCanConvertNodelists) {
57839    toArray = function(arrayLike) {
57840      var arr = new Array(arrayLike.length), i = arrayLike.length;
57841      while (i--) {
57842        arr[i] = arrayLike[i];
57843      }
57844      return arr;
57845    };
57846  }
57847
57848  /**
57849   * Creates specified element with specified attributes
57850   * @memberOf fabric.util
57851   * @param {String} tagName Type of an element to create
57852   * @param {Object} [attributes] Attributes to set on an element
57853   * @return {HTMLElement} Newly created element
57854   */
57855  function makeElement(tagName, attributes) {
57856    var el = fabric.document.createElement(tagName);
57857    for (var prop in attributes) {
57858      if (prop === 'class') {
57859        el.className = attributes[prop];
57860      }
57861      else if (prop === 'for') {
57862        el.htmlFor = attributes[prop];
57863      }
57864      else {
57865        el.setAttribute(prop, attributes[prop]);
57866      }
57867    }
57868    return el;
57869  }
57870
57871  /**
57872   * Adds class to an element
57873   * @memberOf fabric.util
57874   * @param {HTMLElement} element Element to add class to
57875   * @param {String} className Class to add to an element
57876   */
57877  function addClass(element, className) {
57878    if (element && (' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) {
57879      element.className += (element.className ? ' ' : '') + className;
57880    }
57881  }
57882
57883  /**
57884   * Wraps element with another element
57885   * @memberOf fabric.util
57886   * @param {HTMLElement} element Element to wrap
57887   * @param {HTMLElement|String} wrapper Element to wrap with
57888   * @param {Object} [attributes] Attributes to set on a wrapper
57889   * @return {HTMLElement} wrapper
57890   */
57891  function wrapElement(element, wrapper, attributes) {
57892    if (typeof wrapper === 'string') {
57893      wrapper = makeElement(wrapper, attributes);
57894    }
57895    if (element.parentNode) {
57896      element.parentNode.replaceChild(wrapper, element);
57897    }
57898    wrapper.appendChild(element);
57899    return wrapper;
57900  }
57901
57902  /**
57903   * Returns element scroll offsets
57904   * @memberOf fabric.util
57905   * @param {HTMLElement} element Element to operate on
57906   * @return {Object} Object with left/top values
57907   */
57908  function getScrollLeftTop(element) {
57909
57910    var left = 0,
57911        top = 0,
57912        docElement = fabric.document.documentElement,
57913        body = fabric.document.body || {
57914          scrollLeft: 0, scrollTop: 0
57915        };
57916
57917    // While loop checks (and then sets element to) .parentNode OR .host
57918    //  to account for ShadowDOM. We still want to traverse up out of ShadowDOM,
57919    //  but the .parentNode of a root ShadowDOM node will always be null, instead
57920    //  it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938
57921    while (element && (element.parentNode || element.host)) {
57922
57923      // Set element to element parent, or 'host' in case of ShadowDOM
57924      element = element.parentNode || element.host;
57925
57926      if (element === fabric.document) {
57927        left = body.scrollLeft || docElement.scrollLeft || 0;
57928        top = body.scrollTop ||  docElement.scrollTop || 0;
57929      }
57930      else {
57931        left += element.scrollLeft || 0;
57932        top += element.scrollTop || 0;
57933      }
57934
57935      if (element.nodeType === 1 && element.style.position === 'fixed') {
57936        break;
57937      }
57938    }
57939
57940    return { left: left, top: top };
57941  }
57942
57943  /**
57944   * Returns offset for a given element
57945   * @function
57946   * @memberOf fabric.util
57947   * @param {HTMLElement} element Element to get offset for
57948   * @return {Object} Object with "left" and "top" properties
57949   */
57950  function getElementOffset(element) {
57951    var docElem,
57952        doc = element && element.ownerDocument,
57953        box = { left: 0, top: 0 },
57954        offset = { left: 0, top: 0 },
57955        scrollLeftTop,
57956        offsetAttributes = {
57957          borderLeftWidth: 'left',
57958          borderTopWidth:  'top',
57959          paddingLeft:     'left',
57960          paddingTop:      'top'
57961        };
57962
57963    if (!doc) {
57964      return offset;
57965    }
57966
57967    for (var attr in offsetAttributes) {
57968      offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0;
57969    }
57970
57971    docElem = doc.documentElement;
57972    if ( typeof element.getBoundingClientRect !== 'undefined' ) {
57973      box = element.getBoundingClientRect();
57974    }
57975
57976    scrollLeftTop = getScrollLeftTop(element);
57977
57978    return {
57979      left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,
57980      top: box.top + scrollLeftTop.top - (docElem.clientTop || 0)  + offset.top
57981    };
57982  }
57983
57984  /**
57985   * Returns style attribute value of a given element
57986   * @memberOf fabric.util
57987   * @param {HTMLElement} element Element to get style attribute for
57988   * @param {String} attr Style attribute to get for element
57989   * @return {String} Style attribute value of the given element.
57990   */
57991  var getElementStyle;
57992  if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) {
57993    getElementStyle = function(element, attr) {
57994      var style = fabric.document.defaultView.getComputedStyle(element, null);
57995      return style ? style[attr] : undefined;
57996    };
57997  }
57998  else {
57999    getElementStyle = function(element, attr) {
58000      var value = element.style[attr];
58001      if (!value && element.currentStyle) {
58002        value = element.currentStyle[attr];
58003      }
58004      return value;
58005    };
58006  }
58007
58008  (function () {
58009    var style = fabric.document.documentElement.style,
58010        selectProp = 'userSelect' in style
58011          ? 'userSelect'
58012          : 'MozUserSelect' in style
58013            ? 'MozUserSelect'
58014            : 'WebkitUserSelect' in style
58015              ? 'WebkitUserSelect'
58016              : 'KhtmlUserSelect' in style
58017                ? 'KhtmlUserSelect'
58018                : '';
58019
58020    /**
58021     * Makes element unselectable
58022     * @memberOf fabric.util
58023     * @param {HTMLElement} element Element to make unselectable
58024     * @return {HTMLElement} Element that was passed in
58025     */
58026    function makeElementUnselectable(element) {
58027      if (typeof element.onselectstart !== 'undefined') {
58028        element.onselectstart = fabric.util.falseFunction;
58029      }
58030      if (selectProp) {
58031        element.style[selectProp] = 'none';
58032      }
58033      else if (typeof element.unselectable === 'string') {
58034        element.unselectable = 'on';
58035      }
58036      return element;
58037    }
58038
58039    /**
58040     * Makes element selectable
58041     * @memberOf fabric.util
58042     * @param {HTMLElement} element Element to make selectable
58043     * @return {HTMLElement} Element that was passed in
58044     */
58045    function makeElementSelectable(element) {
58046      if (typeof element.onselectstart !== 'undefined') {
58047        element.onselectstart = null;
58048      }
58049      if (selectProp) {
58050        element.style[selectProp] = '';
58051      }
58052      else if (typeof element.unselectable === 'string') {
58053        element.unselectable = '';
58054      }
58055      return element;
58056    }
58057
58058    fabric.util.makeElementUnselectable = makeElementUnselectable;
58059    fabric.util.makeElementSelectable = makeElementSelectable;
58060  })();
58061
58062  function getNodeCanvas(element) {
58063    var impl = fabric.jsdomImplForWrapper(element);
58064    return impl._canvas || impl._image;
58065  };
58066
58067  function cleanUpJsdomNode(element) {
58068    if (!fabric.isLikelyNode) {
58069      return;
58070    }
58071    var impl = fabric.jsdomImplForWrapper(element);
58072    if (impl) {
58073      impl._image = null;
58074      impl._canvas = null;
58075      // unsure if necessary
58076      impl._currentSrc = null;
58077      impl._attributes = null;
58078      impl._classList = null;
58079    }
58080  }
58081
58082  function setImageSmoothing(ctx, value) {
58083    ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled
58084      || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled;
58085    ctx.imageSmoothingEnabled = value;
58086  }
58087
58088  /**
58089   * setImageSmoothing sets the context imageSmoothingEnabled property.
58090   * Used by canvas and by ImageObject.
58091   * @memberOf fabric.util
58092   * @since 4.0.0
58093   * @param {HTMLRenderingContext2D} ctx to set on
58094   * @param {Boolean} value true or false
58095   */
58096  fabric.util.setImageSmoothing = setImageSmoothing;
58097  fabric.util.getById = getById;
58098  fabric.util.toArray = toArray;
58099  fabric.util.addClass = addClass;
58100  fabric.util.makeElement = makeElement;
58101  fabric.util.wrapElement = wrapElement;
58102  fabric.util.getScrollLeftTop = getScrollLeftTop;
58103  fabric.util.getElementOffset = getElementOffset;
58104  fabric.util.getNodeCanvas = getNodeCanvas;
58105  fabric.util.cleanUpJsdomNode = cleanUpJsdomNode;
58106
58107})();
58108
58109
58110(function() {
58111
58112  function addParamToUrl(url, param) {
58113    return url + (/\?/.test(url) ? '&' : '?') + param;
58114  }
58115
58116  function emptyFn() { }
58117
58118  /**
58119   * Cross-browser abstraction for sending XMLHttpRequest
58120   * @memberOf fabric.util
58121   * @param {String} url URL to send XMLHttpRequest to
58122   * @param {Object} [options] Options object
58123   * @param {String} [options.method="GET"]
58124   * @param {String} [options.parameters] parameters to append to url in GET or in body
58125   * @param {String} [options.body] body to send with POST or PUT request
58126   * @param {Function} options.onComplete Callback to invoke when request is completed
58127   * @return {XMLHttpRequest} request
58128   */
58129  function request(url, options) {
58130    options || (options = { });
58131
58132    var method = options.method ? options.method.toUpperCase() : 'GET',
58133        onComplete = options.onComplete || function() { },
58134        xhr = new fabric.window.XMLHttpRequest(),
58135        body = options.body || options.parameters;
58136
58137    /** @ignore */
58138    xhr.onreadystatechange = function() {
58139      if (xhr.readyState === 4) {
58140        onComplete(xhr);
58141        xhr.onreadystatechange = emptyFn;
58142      }
58143    };
58144
58145    if (method === 'GET') {
58146      body = null;
58147      if (typeof options.parameters === 'string') {
58148        url = addParamToUrl(url, options.parameters);
58149      }
58150    }
58151
58152    xhr.open(method, url, true);
58153
58154    if (method === 'POST' || method === 'PUT') {
58155      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
58156    }
58157
58158    xhr.send(body);
58159    return xhr;
58160  }
58161
58162  fabric.util.request = request;
58163})();
58164
58165
58166/**
58167 * Wrapper around `console.log` (when available)
58168 * @param {*} [values] Values to log
58169 */
58170fabric.log = console.log;
58171
58172/**
58173 * Wrapper around `console.warn` (when available)
58174 * @param {*} [values] Values to log as a warning
58175 */
58176fabric.warn = console.warn;
58177
58178
58179(function() {
58180
58181  function noop() {
58182    return false;
58183  }
58184
58185  function defaultEasing(t, b, c, d) {
58186    return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
58187  }
58188
58189  /**
58190   * Changes value from one to another within certain period of time, invoking callbacks as value is being changed.
58191   * @memberOf fabric.util
58192   * @param {Object} [options] Animation options
58193   * @param {Function} [options.onChange] Callback; invoked on every value change
58194   * @param {Function} [options.onComplete] Callback; invoked when value change is completed
58195   * @param {Number} [options.startValue=0] Starting value
58196   * @param {Number} [options.endValue=100] Ending value
58197   * @param {Number} [options.byValue=100] Value to modify the property by
58198   * @param {Function} [options.easing] Easing function
58199   * @param {Number} [options.duration=500] Duration of change (in ms)
58200   * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called.
58201   * @returns {Function} abort function
58202   */
58203  function animate(options) {
58204    var cancel = false;
58205    requestAnimFrame(function(timestamp) {
58206      options || (options = { });
58207
58208      var start = timestamp || +new Date(),
58209          duration = options.duration || 500,
58210          finish = start + duration, time,
58211          onChange = options.onChange || noop,
58212          abort = options.abort || noop,
58213          onComplete = options.onComplete || noop,
58214          easing = options.easing || defaultEasing,
58215          startValue = 'startValue' in options ? options.startValue : 0,
58216          endValue = 'endValue' in options ? options.endValue : 100,
58217          byValue = options.byValue || endValue - startValue;
58218
58219      options.onStart && options.onStart();
58220
58221      (function tick(ticktime) {
58222        // TODO: move abort call after calculation
58223        // and pass (current,valuePerc, timePerc) as arguments
58224        time = ticktime || +new Date();
58225        var currentTime = time > finish ? duration : (time - start),
58226            timePerc = currentTime / duration,
58227            current = easing(currentTime, startValue, byValue, duration),
58228            valuePerc = Math.abs((current - startValue) / byValue);
58229        if (cancel) {
58230          return;
58231        }
58232        if (abort(current, valuePerc, timePerc)) {
58233          // remove this in 4.0
58234          // does to even make sense to abort and run onComplete?
58235          onComplete(endValue, 1, 1);
58236          return;
58237        }
58238        if (time > finish) {
58239          onChange(endValue, 1, 1);
58240          onComplete(endValue, 1, 1);
58241          return;
58242        }
58243        else {
58244          onChange(current, valuePerc, timePerc);
58245          requestAnimFrame(tick);
58246        }
58247      })(start);
58248    });
58249    return function() {
58250      cancel = true;
58251    };
58252  }
58253
58254  var _requestAnimFrame = fabric.window.requestAnimationFrame       ||
58255                          fabric.window.webkitRequestAnimationFrame ||
58256                          fabric.window.mozRequestAnimationFrame    ||
58257                          fabric.window.oRequestAnimationFrame      ||
58258                          fabric.window.msRequestAnimationFrame     ||
58259                          function(callback) {
58260                            return fabric.window.setTimeout(callback, 1000 / 60);
58261                          };
58262
58263  var _cancelAnimFrame = fabric.window.cancelAnimationFrame || fabric.window.clearTimeout;
58264
58265  /**
58266   * requestAnimationFrame polyfill based on http://paulirish.com/2011/requestanimationframe-for-smart-animating/
58267   * In order to get a precise start time, `requestAnimFrame` should be called as an entry into the method
58268   * @memberOf fabric.util
58269   * @param {Function} callback Callback to invoke
58270   * @param {DOMElement} element optional Element to associate with animation
58271   */
58272  function requestAnimFrame() {
58273    return _requestAnimFrame.apply(fabric.window, arguments);
58274  }
58275
58276  function cancelAnimFrame() {
58277    return _cancelAnimFrame.apply(fabric.window, arguments);
58278  }
58279
58280  fabric.util.animate = animate;
58281  fabric.util.requestAnimFrame = requestAnimFrame;
58282  fabric.util.cancelAnimFrame = cancelAnimFrame;
58283})();
58284
58285
58286(function() {
58287  // Calculate an in-between color. Returns a "rgba()" string.
58288  // Credit: Edwin Martin <[email protected]>
58289  //         http://www.bitstorm.org/jquery/color-animation/jquery.animate-colors.js
58290  function calculateColor(begin, end, pos) {
58291    var color = 'rgba('
58292        + parseInt((begin[0] + pos * (end[0] - begin[0])), 10) + ','
58293        + parseInt((begin[1] + pos * (end[1] - begin[1])), 10) + ','
58294        + parseInt((begin[2] + pos * (end[2] - begin[2])), 10);
58295
58296    color += ',' + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1);
58297    color += ')';
58298    return color;
58299  }
58300
58301  /**
58302   * Changes the color from one to another within certain period of time, invoking callbacks as value is being changed.
58303   * @memberOf fabric.util
58304   * @param {String} fromColor The starting color in hex or rgb(a) format.
58305   * @param {String} toColor The starting color in hex or rgb(a) format.
58306   * @param {Number} [duration] Duration of change (in ms).
58307   * @param {Object} [options] Animation options
58308   * @param {Function} [options.onChange] Callback; invoked on every value change
58309   * @param {Function} [options.onComplete] Callback; invoked when value change is completed
58310   * @param {Function} [options.colorEasing] Easing function. Note that this function only take two arguments (currentTime, duration). Thus the regular animation easing functions cannot be used.
58311   * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called.
58312   * @returns {Function} abort function
58313   */
58314  function animateColor(fromColor, toColor, duration, options) {
58315    var startColor = new fabric.Color(fromColor).getSource(),
58316        endColor = new fabric.Color(toColor).getSource(),
58317        originalOnComplete = options.onComplete,
58318        originalOnChange = options.onChange;
58319    options = options || {};
58320
58321    return fabric.util.animate(fabric.util.object.extend(options, {
58322      duration: duration || 500,
58323      startValue: startColor,
58324      endValue: endColor,
58325      byValue: endColor,
58326      easing: function (currentTime, startValue, byValue, duration) {
58327        var posValue = options.colorEasing
58328          ? options.colorEasing(currentTime, duration)
58329          : 1 - Math.cos(currentTime / duration * (Math.PI / 2));
58330        return calculateColor(startValue, byValue, posValue);
58331      },
58332      // has to take in account for color restoring;
58333      onComplete: function(current, valuePerc, timePerc) {
58334        if (originalOnComplete) {
58335          return originalOnComplete(
58336            calculateColor(endColor, endColor, 0),
58337            valuePerc,
58338            timePerc
58339          );
58340        }
58341      },
58342      onChange: function(current, valuePerc, timePerc) {
58343        if (originalOnChange) {
58344          if (Array.isArray(current)) {
58345            return originalOnChange(
58346              calculateColor(current, current, 0),
58347              valuePerc,
58348              timePerc
58349            );
58350          }
58351          originalOnChange(current, valuePerc, timePerc);
58352        }
58353      }
58354    }));
58355  }
58356
58357  fabric.util.animateColor = animateColor;
58358
58359})();
58360
58361
58362(function() {
58363
58364  function normalize(a, c, p, s) {
58365    if (a < Math.abs(c)) {
58366      a = c;
58367      s = p / 4;
58368    }
58369    else {
58370      //handle the 0/0 case:
58371      if (c === 0 && a === 0) {
58372        s = p / (2 * Math.PI) * Math.asin(1);
58373      }
58374      else {
58375        s = p / (2 * Math.PI) * Math.asin(c / a);
58376      }
58377    }
58378    return { a: a, c: c, p: p, s: s };
58379  }
58380
58381  function elastic(opts, t, d) {
58382    return opts.a *
58383      Math.pow(2, 10 * (t -= 1)) *
58384      Math.sin( (t * d - opts.s) * (2 * Math.PI) / opts.p );
58385  }
58386
58387  /**
58388   * Cubic easing out
58389   * @memberOf fabric.util.ease
58390   */
58391  function easeOutCubic(t, b, c, d) {
58392    return c * ((t = t / d - 1) * t * t + 1) + b;
58393  }
58394
58395  /**
58396   * Cubic easing in and out
58397   * @memberOf fabric.util.ease
58398   */
58399  function easeInOutCubic(t, b, c, d) {
58400    t /= d / 2;
58401    if (t < 1) {
58402      return c / 2 * t * t * t + b;
58403    }
58404    return c / 2 * ((t -= 2) * t * t + 2) + b;
58405  }
58406
58407  /**
58408   * Quartic easing in
58409   * @memberOf fabric.util.ease
58410   */
58411  function easeInQuart(t, b, c, d) {
58412    return c * (t /= d) * t * t * t + b;
58413  }
58414
58415  /**
58416   * Quartic easing out
58417   * @memberOf fabric.util.ease
58418   */
58419  function easeOutQuart(t, b, c, d) {
58420    return -c * ((t = t / d - 1) * t * t * t - 1) + b;
58421  }
58422
58423  /**
58424   * Quartic easing in and out
58425   * @memberOf fabric.util.ease
58426   */
58427  function easeInOutQuart(t, b, c, d) {
58428    t /= d / 2;
58429    if (t < 1) {
58430      return c / 2 * t * t * t * t + b;
58431    }
58432    return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
58433  }
58434
58435  /**
58436   * Quintic easing in
58437   * @memberOf fabric.util.ease
58438   */
58439  function easeInQuint(t, b, c, d) {
58440    return c * (t /= d) * t * t * t * t + b;
58441  }
58442
58443  /**
58444   * Quintic easing out
58445   * @memberOf fabric.util.ease
58446   */
58447  function easeOutQuint(t, b, c, d) {
58448    return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
58449  }
58450
58451  /**
58452   * Quintic easing in and out
58453   * @memberOf fabric.util.ease
58454   */
58455  function easeInOutQuint(t, b, c, d) {
58456    t /= d / 2;
58457    if (t < 1) {
58458      return c / 2 * t * t * t * t * t + b;
58459    }
58460    return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
58461  }
58462
58463  /**
58464   * Sinusoidal easing in
58465   * @memberOf fabric.util.ease
58466   */
58467  function easeInSine(t, b, c, d) {
58468    return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
58469  }
58470
58471  /**
58472   * Sinusoidal easing out
58473   * @memberOf fabric.util.ease
58474   */
58475  function easeOutSine(t, b, c, d) {
58476    return c * Math.sin(t / d * (Math.PI / 2)) + b;
58477  }
58478
58479  /**
58480   * Sinusoidal easing in and out
58481   * @memberOf fabric.util.ease
58482   */
58483  function easeInOutSine(t, b, c, d) {
58484    return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
58485  }
58486
58487  /**
58488   * Exponential easing in
58489   * @memberOf fabric.util.ease
58490   */
58491  function easeInExpo(t, b, c, d) {
58492    return (t === 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
58493  }
58494
58495  /**
58496   * Exponential easing out
58497   * @memberOf fabric.util.ease
58498   */
58499  function easeOutExpo(t, b, c, d) {
58500    return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
58501  }
58502
58503  /**
58504   * Exponential easing in and out
58505   * @memberOf fabric.util.ease
58506   */
58507  function easeInOutExpo(t, b, c, d) {
58508    if (t === 0) {
58509      return b;
58510    }
58511    if (t === d) {
58512      return b + c;
58513    }
58514    t /= d / 2;
58515    if (t < 1) {
58516      return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
58517    }
58518    return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
58519  }
58520
58521  /**
58522   * Circular easing in
58523   * @memberOf fabric.util.ease
58524   */
58525  function easeInCirc(t, b, c, d) {
58526    return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
58527  }
58528
58529  /**
58530   * Circular easing out
58531   * @memberOf fabric.util.ease
58532   */
58533  function easeOutCirc(t, b, c, d) {
58534    return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
58535  }
58536
58537  /**
58538   * Circular easing in and out
58539   * @memberOf fabric.util.ease
58540   */
58541  function easeInOutCirc(t, b, c, d) {
58542    t /= d / 2;
58543    if (t < 1) {
58544      return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
58545    }
58546    return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
58547  }
58548
58549  /**
58550   * Elastic easing in
58551   * @memberOf fabric.util.ease
58552   */
58553  function easeInElastic(t, b, c, d) {
58554    var s = 1.70158, p = 0, a = c;
58555    if (t === 0) {
58556      return b;
58557    }
58558    t /= d;
58559    if (t === 1) {
58560      return b + c;
58561    }
58562    if (!p) {
58563      p = d * 0.3;
58564    }
58565    var opts = normalize(a, c, p, s);
58566    return -elastic(opts, t, d) + b;
58567  }
58568
58569  /**
58570   * Elastic easing out
58571   * @memberOf fabric.util.ease
58572   */
58573  function easeOutElastic(t, b, c, d) {
58574    var s = 1.70158, p = 0, a = c;
58575    if (t === 0) {
58576      return b;
58577    }
58578    t /= d;
58579    if (t === 1) {
58580      return b + c;
58581    }
58582    if (!p) {
58583      p = d * 0.3;
58584    }
58585    var opts = normalize(a, c, p, s);
58586    return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) + opts.c + b;
58587  }
58588
58589  /**
58590   * Elastic easing in and out
58591   * @memberOf fabric.util.ease
58592   */
58593  function easeInOutElastic(t, b, c, d) {
58594    var s = 1.70158, p = 0, a = c;
58595    if (t === 0) {
58596      return b;
58597    }
58598    t /= d / 2;
58599    if (t === 2) {
58600      return b + c;
58601    }
58602    if (!p) {
58603      p = d * (0.3 * 1.5);
58604    }
58605    var opts = normalize(a, c, p, s);
58606    if (t < 1) {
58607      return -0.5 * elastic(opts, t, d) + b;
58608    }
58609    return opts.a * Math.pow(2, -10 * (t -= 1)) *
58610      Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) * 0.5 + opts.c + b;
58611  }
58612
58613  /**
58614   * Backwards easing in
58615   * @memberOf fabric.util.ease
58616   */
58617  function easeInBack(t, b, c, d, s) {
58618    if (s === undefined) {
58619      s = 1.70158;
58620    }
58621    return c * (t /= d) * t * ((s + 1) * t - s) + b;
58622  }
58623
58624  /**
58625   * Backwards easing out
58626   * @memberOf fabric.util.ease
58627   */
58628  function easeOutBack(t, b, c, d, s) {
58629    if (s === undefined) {
58630      s = 1.70158;
58631    }
58632    return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
58633  }
58634
58635  /**
58636   * Backwards easing in and out
58637   * @memberOf fabric.util.ease
58638   */
58639  function easeInOutBack(t, b, c, d, s) {
58640    if (s === undefined) {
58641      s = 1.70158;
58642    }
58643    t /= d / 2;
58644    if (t < 1) {
58645      return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
58646    }
58647    return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
58648  }
58649
58650  /**
58651   * Bouncing easing in
58652   * @memberOf fabric.util.ease
58653   */
58654  function easeInBounce(t, b, c, d) {
58655    return c - easeOutBounce (d - t, 0, c, d) + b;
58656  }
58657
58658  /**
58659   * Bouncing easing out
58660   * @memberOf fabric.util.ease
58661   */
58662  function easeOutBounce(t, b, c, d) {
58663    if ((t /= d) < (1 / 2.75)) {
58664      return c * (7.5625 * t * t) + b;
58665    }
58666    else if (t < (2 / 2.75)) {
58667      return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;
58668    }
58669    else if (t < (2.5 / 2.75)) {
58670      return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;
58671    }
58672    else {
58673      return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;
58674    }
58675  }
58676
58677  /**
58678   * Bouncing easing in and out
58679   * @memberOf fabric.util.ease
58680   */
58681  function easeInOutBounce(t, b, c, d) {
58682    if (t < d / 2) {
58683      return easeInBounce (t * 2, 0, c, d) * 0.5 + b;
58684    }
58685    return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;
58686  }
58687
58688  /**
58689   * Easing functions
58690   * See <a href="http://gizma.com/easing/">Easing Equations by Robert Penner</a>
58691   * @namespace fabric.util.ease
58692   */
58693  fabric.util.ease = {
58694
58695    /**
58696     * Quadratic easing in
58697     * @memberOf fabric.util.ease
58698     */
58699    easeInQuad: function(t, b, c, d) {
58700      return c * (t /= d) * t + b;
58701    },
58702
58703    /**
58704     * Quadratic easing out
58705     * @memberOf fabric.util.ease
58706     */
58707    easeOutQuad: function(t, b, c, d) {
58708      return -c * (t /= d) * (t - 2) + b;
58709    },
58710
58711    /**
58712     * Quadratic easing in and out
58713     * @memberOf fabric.util.ease
58714     */
58715    easeInOutQuad: function(t, b, c, d) {
58716      t /= (d / 2);
58717      if (t < 1) {
58718        return c / 2 * t * t + b;
58719      }
58720      return -c / 2 * ((--t) * (t - 2) - 1) + b;
58721    },
58722
58723    /**
58724     * Cubic easing in
58725     * @memberOf fabric.util.ease
58726     */
58727    easeInCubic: function(t, b, c, d) {
58728      return c * (t /= d) * t * t + b;
58729    },
58730
58731    easeOutCubic: easeOutCubic,
58732    easeInOutCubic: easeInOutCubic,
58733    easeInQuart: easeInQuart,
58734    easeOutQuart: easeOutQuart,
58735    easeInOutQuart: easeInOutQuart,
58736    easeInQuint: easeInQuint,
58737    easeOutQuint: easeOutQuint,
58738    easeInOutQuint: easeInOutQuint,
58739    easeInSine: easeInSine,
58740    easeOutSine: easeOutSine,
58741    easeInOutSine: easeInOutSine,
58742    easeInExpo: easeInExpo,
58743    easeOutExpo: easeOutExpo,
58744    easeInOutExpo: easeInOutExpo,
58745    easeInCirc: easeInCirc,
58746    easeOutCirc: easeOutCirc,
58747    easeInOutCirc: easeInOutCirc,
58748    easeInElastic: easeInElastic,
58749    easeOutElastic: easeOutElastic,
58750    easeInOutElastic: easeInOutElastic,
58751    easeInBack: easeInBack,
58752    easeOutBack: easeOutBack,
58753    easeInOutBack: easeInOutBack,
58754    easeInBounce: easeInBounce,
58755    easeOutBounce: easeOutBounce,
58756    easeInOutBounce: easeInOutBounce
58757  };
58758
58759})();
58760
58761
58762(function(global) {
58763
58764  'use strict';
58765
58766  /**
58767   * @name fabric
58768   * @namespace
58769   */
58770
58771  var fabric = global.fabric || (global.fabric = { }),
58772      extend = fabric.util.object.extend,
58773      clone = fabric.util.object.clone,
58774      toFixed = fabric.util.toFixed,
58775      parseUnit = fabric.util.parseUnit,
58776      multiplyTransformMatrices = fabric.util.multiplyTransformMatrices,
58777
58778      svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line',
58779        'image', 'text'],
58780      svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],
58781      svgInvalidAncestors = ['pattern', 'defs', 'symbol', 'metadata', 'clipPath', 'mask', 'desc'],
58782      svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'],
58783
58784      attributesMap = {
58785        cx:                   'left',
58786        x:                    'left',
58787        r:                    'radius',
58788        cy:                   'top',
58789        y:                    'top',
58790        display:              'visible',
58791        visibility:           'visible',
58792        transform:            'transformMatrix',
58793        'fill-opacity':       'fillOpacity',
58794        'fill-rule':          'fillRule',
58795        'font-family':        'fontFamily',
58796        'font-size':          'fontSize',
58797        'font-style':         'fontStyle',
58798        'font-weight':        'fontWeight',
58799        'letter-spacing':     'charSpacing',
58800        'paint-order':        'paintFirst',
58801        'stroke-dasharray':   'strokeDashArray',
58802        'stroke-dashoffset':  'strokeDashOffset',
58803        'stroke-linecap':     'strokeLineCap',
58804        'stroke-linejoin':    'strokeLineJoin',
58805        'stroke-miterlimit':  'strokeMiterLimit',
58806        'stroke-opacity':     'strokeOpacity',
58807        'stroke-width':       'strokeWidth',
58808        'text-decoration':    'textDecoration',
58809        'text-anchor':        'textAnchor',
58810        opacity:              'opacity',
58811        'clip-path':          'clipPath',
58812        'clip-rule':          'clipRule',
58813        'vector-effect':      'strokeUniform',
58814        'image-rendering':    'imageSmoothing',
58815      },
58816
58817      colorAttributes = {
58818        stroke: 'strokeOpacity',
58819        fill:   'fillOpacity'
58820      },
58821
58822      fSize = 'font-size', cPath = 'clip-path';
58823
58824  fabric.svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);
58825  fabric.svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);
58826  fabric.svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors);
58827  fabric.svgValidParentsRegEx = getSvgRegex(svgValidParents);
58828
58829  fabric.cssRules = { };
58830  fabric.gradientDefs = { };
58831  fabric.clipPaths = { };
58832
58833  function normalizeAttr(attr) {
58834    // transform attribute names
58835    if (attr in attributesMap) {
58836      return attributesMap[attr];
58837    }
58838    return attr;
58839  }
58840
58841  function normalizeValue(attr, value, parentAttributes, fontSize) {
58842    var isArray = Object.prototype.toString.call(value) === '[object Array]',
58843        parsed;
58844
58845    if ((attr === 'fill' || attr === 'stroke') && value === 'none') {
58846      value = '';
58847    }
58848    else if (attr === 'strokeUniform') {
58849      return (value === 'non-scaling-stroke');
58850    }
58851    else if (attr === 'strokeDashArray') {
58852      if (value === 'none') {
58853        value = null;
58854      }
58855      else {
58856        value = value.replace(/,/g, ' ').split(/\s+/).map(parseFloat);
58857      }
58858    }
58859    else if (attr === 'transformMatrix') {
58860      if (parentAttributes && parentAttributes.transformMatrix) {
58861        value = multiplyTransformMatrices(
58862          parentAttributes.transformMatrix, fabric.parseTransformAttribute(value));
58863      }
58864      else {
58865        value = fabric.parseTransformAttribute(value);
58866      }
58867    }
58868    else if (attr === 'visible') {
58869      value = value !== 'none' && value !== 'hidden';
58870      // display=none on parent element always takes precedence over child element
58871      if (parentAttributes && parentAttributes.visible === false) {
58872        value = false;
58873      }
58874    }
58875    else if (attr === 'opacity') {
58876      value = parseFloat(value);
58877      if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {
58878        value *= parentAttributes.opacity;
58879      }
58880    }
58881    else if (attr === 'textAnchor' /* text-anchor */) {
58882      value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center';
58883    }
58884    else if (attr === 'charSpacing') {
58885      // parseUnit returns px and we convert it to em
58886      parsed = parseUnit(value, fontSize) / fontSize * 1000;
58887    }
58888    else if (attr === 'paintFirst') {
58889      var fillIndex = value.indexOf('fill');
58890      var strokeIndex = value.indexOf('stroke');
58891      var value = 'fill';
58892      if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) {
58893        value = 'stroke';
58894      }
58895      else if (fillIndex === -1 && strokeIndex > -1) {
58896        value = 'stroke';
58897      }
58898    }
58899    else if (attr === 'href' || attr === 'xlink:href' || attr === 'font') {
58900      return value;
58901    }
58902    else if (attr === 'imageSmoothing') {
58903      return (value === 'optimizeQuality');
58904    }
58905    else {
58906      parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize);
58907    }
58908
58909    return (!isArray && isNaN(parsed) ? value : parsed);
58910  }
58911
58912  /**
58913    * @private
58914    */
58915  function getSvgRegex(arr) {
58916    return new RegExp('^(' + arr.join('|') + ')\\b', 'i');
58917  }
58918
58919  /**
58920   * @private
58921   * @param {Object} attributes Array of attributes to parse
58922   */
58923  function _setStrokeFillOpacity(attributes) {
58924    for (var attr in colorAttributes) {
58925
58926      if (typeof attributes[colorAttributes[attr]] === 'undefined' || attributes[attr] === '') {
58927        continue;
58928      }
58929
58930      if (typeof attributes[attr] === 'undefined') {
58931        if (!fabric.Object.prototype[attr]) {
58932          continue;
58933        }
58934        attributes[attr] = fabric.Object.prototype[attr];
58935      }
58936
58937      if (attributes[attr].indexOf('url(') === 0) {
58938        continue;
58939      }
58940
58941      var color = new fabric.Color(attributes[attr]);
58942      attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba();
58943    }
58944    return attributes;
58945  }
58946
58947  /**
58948   * @private
58949   */
58950  function _getMultipleNodes(doc, nodeNames) {
58951    var nodeName, nodeArray = [], nodeList, i, len;
58952    for (i = 0, len = nodeNames.length; i < len; i++) {
58953      nodeName = nodeNames[i];
58954      nodeList = doc.getElementsByTagName(nodeName);
58955      nodeArray = nodeArray.concat(Array.prototype.slice.call(nodeList));
58956    }
58957    return nodeArray;
58958  }
58959
58960  /**
58961   * Parses "transform" attribute, returning an array of values
58962   * @static
58963   * @function
58964   * @memberOf fabric
58965   * @param {String} attributeValue String containing attribute value
58966   * @return {Array} Array of 6 elements representing transformation matrix
58967   */
58968  fabric.parseTransformAttribute = (function() {
58969    function rotateMatrix(matrix, args) {
58970      var cos = fabric.util.cos(args[0]), sin = fabric.util.sin(args[0]),
58971          x = 0, y = 0;
58972      if (args.length === 3) {
58973        x = args[1];
58974        y = args[2];
58975      }
58976
58977      matrix[0] = cos;
58978      matrix[1] = sin;
58979      matrix[2] = -sin;
58980      matrix[3] = cos;
58981      matrix[4] = x - (cos * x - sin * y);
58982      matrix[5] = y - (sin * x + cos * y);
58983    }
58984
58985    function scaleMatrix(matrix, args) {
58986      var multiplierX = args[0],
58987          multiplierY = (args.length === 2) ? args[1] : args[0];
58988
58989      matrix[0] = multiplierX;
58990      matrix[3] = multiplierY;
58991    }
58992
58993    function skewMatrix(matrix, args, pos) {
58994      matrix[pos] = Math.tan(fabric.util.degreesToRadians(args[0]));
58995    }
58996
58997    function translateMatrix(matrix, args) {
58998      matrix[4] = args[0];
58999      if (args.length === 2) {
59000        matrix[5] = args[1];
59001      }
59002    }
59003
59004    // identity matrix
59005    var iMatrix = fabric.iMatrix,
59006
59007        // == begin transform regexp
59008        number = fabric.reNum,
59009
59010        commaWsp = fabric.commaWsp,
59011
59012        skewX = '(?:(skewX)\\s*\\(\\s*(' + number + ')\\s*\\))',
59013
59014        skewY = '(?:(skewY)\\s*\\(\\s*(' + number + ')\\s*\\))',
59015
59016        rotate = '(?:(rotate)\\s*\\(\\s*(' + number + ')(?:' +
59017                    commaWsp + '(' + number + ')' +
59018                    commaWsp + '(' + number + '))?\\s*\\))',
59019
59020        scale = '(?:(scale)\\s*\\(\\s*(' + number + ')(?:' +
59021                    commaWsp + '(' + number + '))?\\s*\\))',
59022
59023        translate = '(?:(translate)\\s*\\(\\s*(' + number + ')(?:' +
59024                    commaWsp + '(' + number + '))?\\s*\\))',
59025
59026        matrix = '(?:(matrix)\\s*\\(\\s*' +
59027                  '(' + number + ')' + commaWsp +
59028                  '(' + number + ')' + commaWsp +
59029                  '(' + number + ')' + commaWsp +
59030                  '(' + number + ')' + commaWsp +
59031                  '(' + number + ')' + commaWsp +
59032                  '(' + number + ')' +
59033                  '\\s*\\))',
59034
59035        transform = '(?:' +
59036                    matrix + '|' +
59037                    translate + '|' +
59038                    scale + '|' +
59039                    rotate + '|' +
59040                    skewX + '|' +
59041                    skewY +
59042                    ')',
59043
59044        transforms = '(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')',
59045
59046        transformList = '^\\s*(?:' + transforms + '?)\\s*$',
59047
59048        // http://www.w3.org/TR/SVG/coords.html#TransformAttribute
59049        reTransformList = new RegExp(transformList),
59050        // == end transform regexp
59051
59052        reTransform = new RegExp(transform, 'g');
59053
59054    return function(attributeValue) {
59055
59056      // start with identity matrix
59057      var matrix = iMatrix.concat(),
59058          matrices = [];
59059
59060      // return if no argument was given or
59061      // an argument does not match transform attribute regexp
59062      if (!attributeValue || (attributeValue && !reTransformList.test(attributeValue))) {
59063        return matrix;
59064      }
59065
59066      attributeValue.replace(reTransform, function(match) {
59067
59068        var m = new RegExp(transform).exec(match).filter(function (match) {
59069              // match !== '' && match != null
59070              return (!!match);
59071            }),
59072            operation = m[1],
59073            args = m.slice(2).map(parseFloat);
59074
59075        switch (operation) {
59076          case 'translate':
59077            translateMatrix(matrix, args);
59078            break;
59079          case 'rotate':
59080            args[0] = fabric.util.degreesToRadians(args[0]);
59081            rotateMatrix(matrix, args);
59082            break;
59083          case 'scale':
59084            scaleMatrix(matrix, args);
59085            break;
59086          case 'skewX':
59087            skewMatrix(matrix, args, 2);
59088            break;
59089          case 'skewY':
59090            skewMatrix(matrix, args, 1);
59091            break;
59092          case 'matrix':
59093            matrix = args;
59094            break;
59095        }
59096
59097        // snapshot current matrix into matrices array
59098        matrices.push(matrix.concat());
59099        // reset
59100        matrix = iMatrix.concat();
59101      });
59102
59103      var combinedMatrix = matrices[0];
59104      while (matrices.length > 1) {
59105        matrices.shift();
59106        combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]);
59107      }
59108      return combinedMatrix;
59109    };
59110  })();
59111
59112  /**
59113   * @private
59114   */
59115  function parseStyleString(style, oStyle) {
59116    var attr, value;
59117    style.replace(/;\s*$/, '').split(';').forEach(function (chunk) {
59118      var pair = chunk.split(':');
59119
59120      attr = pair[0].trim().toLowerCase();
59121      value =  pair[1].trim();
59122
59123      oStyle[attr] = value;
59124    });
59125  }
59126
59127  /**
59128   * @private
59129   */
59130  function parseStyleObject(style, oStyle) {
59131    var attr, value;
59132    for (var prop in style) {
59133      if (typeof style[prop] === 'undefined') {
59134        continue;
59135      }
59136
59137      attr = prop.toLowerCase();
59138      value = style[prop];
59139
59140      oStyle[attr] = value;
59141    }
59142  }
59143
59144  /**
59145   * @private
59146   */
59147  function getGlobalStylesForElement(element, svgUid) {
59148    var styles = { };
59149    for (var rule in fabric.cssRules[svgUid]) {
59150      if (elementMatchesRule(element, rule.split(' '))) {
59151        for (var property in fabric.cssRules[svgUid][rule]) {
59152          styles[property] = fabric.cssRules[svgUid][rule][property];
59153        }
59154      }
59155    }
59156    return styles;
59157  }
59158
59159  /**
59160   * @private
59161   */
59162  function elementMatchesRule(element, selectors) {
59163    var firstMatching, parentMatching = true;
59164    //start from rightmost selector.
59165    firstMatching = selectorMatches(element, selectors.pop());
59166    if (firstMatching && selectors.length) {
59167      parentMatching = doesSomeParentMatch(element, selectors);
59168    }
59169    return firstMatching && parentMatching && (selectors.length === 0);
59170  }
59171
59172  function doesSomeParentMatch(element, selectors) {
59173    var selector, parentMatching = true;
59174    while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) {
59175      if (parentMatching) {
59176        selector = selectors.pop();
59177      }
59178      element = element.parentNode;
59179      parentMatching = selectorMatches(element, selector);
59180    }
59181    return selectors.length === 0;
59182  }
59183
59184  /**
59185   * @private
59186   */
59187  function selectorMatches(element, selector) {
59188    var nodeName = element.nodeName,
59189        classNames = element.getAttribute('class'),
59190        id = element.getAttribute('id'), matcher, i;
59191    // i check if a selector matches slicing away part from it.
59192    // if i get empty string i should match
59193    matcher = new RegExp('^' + nodeName, 'i');
59194    selector = selector.replace(matcher, '');
59195    if (id && selector.length) {
59196      matcher = new RegExp('#' + id + '(?![a-zA-Z\\-]+)', 'i');
59197      selector = selector.replace(matcher, '');
59198    }
59199    if (classNames && selector.length) {
59200      classNames = classNames.split(' ');
59201      for (i = classNames.length; i--;) {
59202        matcher = new RegExp('\\.' + classNames[i] + '(?![a-zA-Z\\-]+)', 'i');
59203        selector = selector.replace(matcher, '');
59204      }
59205    }
59206    return selector.length === 0;
59207  }
59208
59209  /**
59210   * @private
59211   * to support IE8 missing getElementById on SVGdocument and on node xmlDOM
59212   */
59213  function elementById(doc, id) {
59214    var el;
59215    doc.getElementById && (el = doc.getElementById(id));
59216    if (el) {
59217      return el;
59218    }
59219    var node, i, len, nodelist = doc.getElementsByTagName('*');
59220    for (i = 0, len = nodelist.length; i < len; i++) {
59221      node = nodelist[i];
59222      if (id === node.getAttribute('id')) {
59223        return node;
59224      }
59225    }
59226  }
59227
59228  /**
59229   * @private
59230   */
59231  function parseUseDirectives(doc) {
59232    var nodelist = _getMultipleNodes(doc, ['use', 'svg:use']), i = 0;
59233    while (nodelist.length && i < nodelist.length) {
59234      var el = nodelist[i],
59235          xlinkAttribute = el.getAttribute('xlink:href') || el.getAttribute('href');
59236
59237      if (xlinkAttribute === null) {
59238        return;
59239      }
59240
59241      var xlink = xlinkAttribute.substr(1),
59242          x = el.getAttribute('x') || 0,
59243          y = el.getAttribute('y') || 0,
59244          el2 = elementById(doc, xlink).cloneNode(true),
59245          currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')',
59246          parentNode,
59247          oldLength = nodelist.length, attr,
59248          j,
59249          attrs,
59250          len,
59251          namespace = fabric.svgNS;
59252
59253      applyViewboxTransform(el2);
59254      if (/^svg$/i.test(el2.nodeName)) {
59255        var el3 = el2.ownerDocument.createElementNS(namespace, 'g');
59256        for (j = 0, attrs = el2.attributes, len = attrs.length; j < len; j++) {
59257          attr = attrs.item(j);
59258          el3.setAttributeNS(namespace, attr.nodeName, attr.nodeValue);
59259        }
59260        // el2.firstChild != null
59261        while (el2.firstChild) {
59262          el3.appendChild(el2.firstChild);
59263        }
59264        el2 = el3;
59265      }
59266
59267      for (j = 0, attrs = el.attributes, len = attrs.length; j < len; j++) {
59268        attr = attrs.item(j);
59269        if (attr.nodeName === 'x' || attr.nodeName === 'y' ||
59270          attr.nodeName === 'xlink:href' || attr.nodeName === 'href') {
59271          continue;
59272        }
59273
59274        if (attr.nodeName === 'transform') {
59275          currentTrans = attr.nodeValue + ' ' + currentTrans;
59276        }
59277        else {
59278          el2.setAttribute(attr.nodeName, attr.nodeValue);
59279        }
59280      }
59281
59282      el2.setAttribute('transform', currentTrans);
59283      el2.setAttribute('instantiated_by_use', '1');
59284      el2.removeAttribute('id');
59285      parentNode = el.parentNode;
59286      parentNode.replaceChild(el2, el);
59287      // some browsers do not shorten nodelist after replaceChild (IE8)
59288      if (nodelist.length === oldLength) {
59289        i++;
59290      }
59291    }
59292  }
59293
59294  // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
59295  // matches, e.g.: +14.56e-12, etc.
59296  var reViewBoxAttrValue = new RegExp(
59297    '^' +
59298    '\\s*(' + fabric.reNum + '+)\\s*,?' +
59299    '\\s*(' + fabric.reNum + '+)\\s*,?' +
59300    '\\s*(' + fabric.reNum + '+)\\s*,?' +
59301    '\\s*(' + fabric.reNum + '+)\\s*' +
59302    '$'
59303  );
59304
59305  /**
59306   * Add a <g> element that envelop all child elements and makes the viewbox transformMatrix descend on all elements
59307   */
59308  function applyViewboxTransform(element) {
59309    if (!fabric.svgViewBoxElementsRegEx.test(element.nodeName)) {
59310      return {};
59311    }
59312    var viewBoxAttr = element.getAttribute('viewBox'),
59313        scaleX = 1,
59314        scaleY = 1,
59315        minX = 0,
59316        minY = 0,
59317        viewBoxWidth, viewBoxHeight, matrix, el,
59318        widthAttr = element.getAttribute('width'),
59319        heightAttr = element.getAttribute('height'),
59320        x = element.getAttribute('x') || 0,
59321        y = element.getAttribute('y') || 0,
59322        preserveAspectRatio = element.getAttribute('preserveAspectRatio') || '',
59323        missingViewBox = (!viewBoxAttr || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))),
59324        missingDimAttr = (!widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%'),
59325        toBeParsed = missingViewBox && missingDimAttr,
59326        parsedDim = { }, translateMatrix = '', widthDiff = 0, heightDiff = 0;
59327
59328    parsedDim.width = 0;
59329    parsedDim.height = 0;
59330    parsedDim.toBeParsed = toBeParsed;
59331
59332    if (missingViewBox) {
59333      if (((x || y) && element.parentNode && element.parentNode.nodeName !== '#document')) {
59334        translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';
59335        matrix = (element.getAttribute('transform') || '') + translateMatrix;
59336        element.setAttribute('transform', matrix);
59337        element.removeAttribute('x');
59338        element.removeAttribute('y');
59339      }
59340    }
59341
59342    if (toBeParsed) {
59343      return parsedDim;
59344    }
59345
59346    if (missingViewBox) {
59347      parsedDim.width = parseUnit(widthAttr);
59348      parsedDim.height = parseUnit(heightAttr);
59349      // set a transform for elements that have x y and are inner(only) SVGs
59350      return parsedDim;
59351    }
59352    minX = -parseFloat(viewBoxAttr[1]);
59353    minY = -parseFloat(viewBoxAttr[2]);
59354    viewBoxWidth = parseFloat(viewBoxAttr[3]);
59355    viewBoxHeight = parseFloat(viewBoxAttr[4]);
59356    parsedDim.minX = minX;
59357    parsedDim.minY = minY;
59358    parsedDim.viewBoxWidth = viewBoxWidth;
59359    parsedDim.viewBoxHeight = viewBoxHeight;
59360    if (!missingDimAttr) {
59361      parsedDim.width = parseUnit(widthAttr);
59362      parsedDim.height = parseUnit(heightAttr);
59363      scaleX = parsedDim.width / viewBoxWidth;
59364      scaleY = parsedDim.height / viewBoxHeight;
59365    }
59366    else {
59367      parsedDim.width = viewBoxWidth;
59368      parsedDim.height = viewBoxHeight;
59369    }
59370
59371    // default is to preserve aspect ratio
59372    preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio);
59373    if (preserveAspectRatio.alignX !== 'none') {
59374      //translate all container for the effect of Mid, Min, Max
59375      if (preserveAspectRatio.meetOrSlice === 'meet') {
59376        scaleY = scaleX = (scaleX > scaleY ? scaleY : scaleX);
59377        // calculate additional translation to move the viewbox
59378      }
59379      if (preserveAspectRatio.meetOrSlice === 'slice') {
59380        scaleY = scaleX = (scaleX > scaleY ? scaleX : scaleY);
59381        // calculate additional translation to move the viewbox
59382      }
59383      widthDiff = parsedDim.width - viewBoxWidth * scaleX;
59384      heightDiff = parsedDim.height - viewBoxHeight * scaleX;
59385      if (preserveAspectRatio.alignX === 'Mid') {
59386        widthDiff /= 2;
59387      }
59388      if (preserveAspectRatio.alignY === 'Mid') {
59389        heightDiff /= 2;
59390      }
59391      if (preserveAspectRatio.alignX === 'Min') {
59392        widthDiff = 0;
59393      }
59394      if (preserveAspectRatio.alignY === 'Min') {
59395        heightDiff = 0;
59396      }
59397    }
59398
59399    if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) {
59400      return parsedDim;
59401    }
59402    if ((x || y) && element.parentNode.nodeName !== '#document') {
59403      translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';
59404    }
59405
59406    matrix = translateMatrix + ' matrix(' + scaleX +
59407                  ' 0' +
59408                  ' 0 ' +
59409                  scaleY + ' ' +
59410                  (minX * scaleX + widthDiff) + ' ' +
59411                  (minY * scaleY + heightDiff) + ') ';
59412    // seems unused.
59413    // parsedDim.viewboxTransform = fabric.parseTransformAttribute(matrix);
59414    if (element.nodeName === 'svg') {
59415      el = element.ownerDocument.createElementNS(fabric.svgNS, 'g');
59416      // element.firstChild != null
59417      while (element.firstChild) {
59418        el.appendChild(element.firstChild);
59419      }
59420      element.appendChild(el);
59421    }
59422    else {
59423      el = element;
59424      el.removeAttribute('x');
59425      el.removeAttribute('y');
59426      matrix = el.getAttribute('transform') + matrix;
59427    }
59428    el.setAttribute('transform', matrix);
59429    return parsedDim;
59430  }
59431
59432  function hasAncestorWithNodeName(element, nodeName) {
59433    while (element && (element = element.parentNode)) {
59434      if (element.nodeName && nodeName.test(element.nodeName.replace('svg:', ''))
59435        && !element.getAttribute('instantiated_by_use')) {
59436        return true;
59437      }
59438    }
59439    return false;
59440  }
59441
59442  /**
59443   * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback
59444   * @static
59445   * @function
59446   * @memberOf fabric
59447   * @param {SVGDocument} doc SVG document to parse
59448   * @param {Function} callback Callback to call when parsing is finished;
59449   * It's being passed an array of elements (parsed from a document).
59450   * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
59451   * @param {Object} [parsingOptions] options for parsing document
59452   * @param {String} [parsingOptions.crossOrigin] crossOrigin settings
59453   */
59454  fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) {
59455    if (!doc) {
59456      return;
59457    }
59458
59459    parseUseDirectives(doc);
59460
59461    var svgUid =  fabric.Object.__uid++, i, len,
59462        options = applyViewboxTransform(doc),
59463        descendants = fabric.util.toArray(doc.getElementsByTagName('*'));
59464    options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;
59465    options.svgUid = svgUid;
59466
59467    if (descendants.length === 0 && fabric.isLikelyNode) {
59468      // we're likely in node, where "o3-xml" library fails to gEBTN("*")
59469      // https://github.com/ajaxorg/node-o3-xml/issues/21
59470      descendants = doc.selectNodes('//*[name(.)!="svg"]');
59471      var arr = [];
59472      for (i = 0, len = descendants.length; i < len; i++) {
59473        arr[i] = descendants[i];
59474      }
59475      descendants = arr;
59476    }
59477
59478    var elements = descendants.filter(function(el) {
59479      applyViewboxTransform(el);
59480      return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')) &&
59481            !hasAncestorWithNodeName(el, fabric.svgInvalidAncestorsRegEx); // http://www.w3.org/TR/SVG/struct.html#DefsElement
59482    });
59483    if (!elements || (elements && !elements.length)) {
59484      callback && callback([], {});
59485      return;
59486    }
59487    var clipPaths = { };
59488    descendants.filter(function(el) {
59489      return el.nodeName.replace('svg:', '') === 'clipPath';
59490    }).forEach(function(el) {
59491      var id = el.getAttribute('id');
59492      clipPaths[id] = fabric.util.toArray(el.getElementsByTagName('*')).filter(function(el) {
59493        return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', ''));
59494      });
59495    });
59496    fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc);
59497    fabric.cssRules[svgUid] = fabric.getCSSRules(doc);
59498    fabric.clipPaths[svgUid] = clipPaths;
59499    // Precedence of rules:   style > class > attribute
59500    fabric.parseElements(elements, function(instances, elements) {
59501      if (callback) {
59502        callback(instances, options, elements, descendants);
59503        delete fabric.gradientDefs[svgUid];
59504        delete fabric.cssRules[svgUid];
59505        delete fabric.clipPaths[svgUid];
59506      }
59507    }, clone(options), reviver, parsingOptions);
59508  };
59509
59510  function recursivelyParseGradientsXlink(doc, gradient) {
59511    var gradientsAttrs = ['gradientTransform', 'x1', 'x2', 'y1', 'y2', 'gradientUnits', 'cx', 'cy', 'r', 'fx', 'fy'],
59512        xlinkAttr = 'xlink:href',
59513        xLink = gradient.getAttribute(xlinkAttr).substr(1),
59514        referencedGradient = elementById(doc, xLink);
59515    if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) {
59516      recursivelyParseGradientsXlink(doc, referencedGradient);
59517    }
59518    gradientsAttrs.forEach(function(attr) {
59519      if (referencedGradient && !gradient.hasAttribute(attr) && referencedGradient.hasAttribute(attr)) {
59520        gradient.setAttribute(attr, referencedGradient.getAttribute(attr));
59521      }
59522    });
59523    if (!gradient.children.length) {
59524      var referenceClone = referencedGradient.cloneNode(true);
59525      while (referenceClone.firstChild) {
59526        gradient.appendChild(referenceClone.firstChild);
59527      }
59528    }
59529    gradient.removeAttribute(xlinkAttr);
59530  }
59531
59532  var reFontDeclaration = new RegExp(
59533    '(normal|italic)?\\s*(normal|small-caps)?\\s*' +
59534    '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(' +
59535      fabric.reNum +
59536    '(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|' + fabric.reNum + '))?\\s+(.*)');
59537
59538  extend(fabric, {
59539    /**
59540     * Parses a short font declaration, building adding its properties to a style object
59541     * @static
59542     * @function
59543     * @memberOf fabric
59544     * @param {String} value font declaration
59545     * @param {Object} oStyle definition
59546     */
59547    parseFontDeclaration: function(value, oStyle) {
59548      var match = value.match(reFontDeclaration);
59549
59550      if (!match) {
59551        return;
59552      }
59553      var fontStyle = match[1],
59554          // font variant is not used
59555          // fontVariant = match[2],
59556          fontWeight = match[3],
59557          fontSize = match[4],
59558          lineHeight = match[5],
59559          fontFamily = match[6];
59560
59561      if (fontStyle) {
59562        oStyle.fontStyle = fontStyle;
59563      }
59564      if (fontWeight) {
59565        oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight);
59566      }
59567      if (fontSize) {
59568        oStyle.fontSize = parseUnit(fontSize);
59569      }
59570      if (fontFamily) {
59571        oStyle.fontFamily = fontFamily;
59572      }
59573      if (lineHeight) {
59574        oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight;
59575      }
59576    },
59577
59578    /**
59579     * Parses an SVG document, returning all of the gradient declarations found in it
59580     * @static
59581     * @function
59582     * @memberOf fabric
59583     * @param {SVGDocument} doc SVG document to parse
59584     * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element
59585     */
59586    getGradientDefs: function(doc) {
59587      var tagArray = [
59588            'linearGradient',
59589            'radialGradient',
59590            'svg:linearGradient',
59591            'svg:radialGradient'],
59592          elList = _getMultipleNodes(doc, tagArray),
59593          el, j = 0, gradientDefs = { };
59594      j = elList.length;
59595      while (j--) {
59596        el = elList[j];
59597        if (el.getAttribute('xlink:href')) {
59598          recursivelyParseGradientsXlink(doc, el);
59599        }
59600        gradientDefs[el.getAttribute('id')] = el;
59601      }
59602      return gradientDefs;
59603    },
59604
59605    /**
59606     * Returns an object of attributes' name/value, given element and an array of attribute names;
59607     * Parses parent "g" nodes recursively upwards.
59608     * @static
59609     * @memberOf fabric
59610     * @param {DOMElement} element Element to parse
59611     * @param {Array} attributes Array of attributes to parse
59612     * @return {Object} object containing parsed attributes' names/values
59613     */
59614    parseAttributes: function(element, attributes, svgUid) {
59615
59616      if (!element) {
59617        return;
59618      }
59619
59620      var value,
59621          parentAttributes = { },
59622          fontSize, parentFontSize;
59623
59624      if (typeof svgUid === 'undefined') {
59625        svgUid = element.getAttribute('svgUid');
59626      }
59627      // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards
59628      if (element.parentNode && fabric.svgValidParentsRegEx.test(element.parentNode.nodeName)) {
59629        parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid);
59630      }
59631
59632      var ownAttributes = attributes.reduce(function(memo, attr) {
59633        value = element.getAttribute(attr);
59634        if (value) { // eslint-disable-line
59635          memo[attr] = value;
59636        }
59637        return memo;
59638      }, { });
59639      // add values parsed from style, which take precedence over attributes
59640      // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)
59641      var cssAttrs = extend(
59642        getGlobalStylesForElement(element, svgUid),
59643        fabric.parseStyleAttribute(element)
59644      );
59645      ownAttributes = extend(
59646        ownAttributes,
59647        cssAttrs
59648      );
59649      if (cssAttrs[cPath]) {
59650        element.setAttribute(cPath, cssAttrs[cPath]);
59651      }
59652      fontSize = parentFontSize = parentAttributes.fontSize || fabric.Text.DEFAULT_SVG_FONT_SIZE;
59653      if (ownAttributes[fSize]) {
59654        // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers.
59655        ownAttributes[fSize] = fontSize = parseUnit(ownAttributes[fSize], parentFontSize);
59656      }
59657
59658      var normalizedAttr, normalizedValue, normalizedStyle = {};
59659      for (var attr in ownAttributes) {
59660        normalizedAttr = normalizeAttr(attr);
59661        normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize);
59662        normalizedStyle[normalizedAttr] = normalizedValue;
59663      }
59664      if (normalizedStyle && normalizedStyle.font) {
59665        fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);
59666      }
59667      var mergedAttrs = extend(parentAttributes, normalizedStyle);
59668      return fabric.svgValidParentsRegEx.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);
59669    },
59670
59671    /**
59672     * Transforms an array of svg elements to corresponding fabric.* instances
59673     * @static
59674     * @memberOf fabric
59675     * @param {Array} elements Array of elements to parse
59676     * @param {Function} callback Being passed an array of fabric instances (transformed from SVG elements)
59677     * @param {Object} [options] Options object
59678     * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
59679     */
59680    parseElements: function(elements, callback, options, reviver, parsingOptions) {
59681      new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse();
59682    },
59683
59684    /**
59685     * Parses "style" attribute, retuning an object with values
59686     * @static
59687     * @memberOf fabric
59688     * @param {SVGElement} element Element to parse
59689     * @return {Object} Objects with values parsed from style attribute of an element
59690     */
59691    parseStyleAttribute: function(element) {
59692      var oStyle = { },
59693          style = element.getAttribute('style');
59694
59695      if (!style) {
59696        return oStyle;
59697      }
59698
59699      if (typeof style === 'string') {
59700        parseStyleString(style, oStyle);
59701      }
59702      else {
59703        parseStyleObject(style, oStyle);
59704      }
59705
59706      return oStyle;
59707    },
59708
59709    /**
59710     * Parses "points" attribute, returning an array of values
59711     * @static
59712     * @memberOf fabric
59713     * @param {String} points points attribute string
59714     * @return {Array} array of points
59715     */
59716    parsePointsAttribute: function(points) {
59717
59718      // points attribute is required and must not be empty
59719      if (!points) {
59720        return null;
59721      }
59722
59723      // replace commas with whitespace and remove bookending whitespace
59724      points = points.replace(/,/g, ' ').trim();
59725
59726      points = points.split(/\s+/);
59727      var parsedPoints = [], i, len;
59728
59729      for (i = 0, len = points.length; i < len; i += 2) {
59730        parsedPoints.push({
59731          x: parseFloat(points[i]),
59732          y: parseFloat(points[i + 1])
59733        });
59734      }
59735
59736      // odd number of points is an error
59737      // if (parsedPoints.length % 2 !== 0) {
59738      //   return null;
59739      // }
59740
59741      return parsedPoints;
59742    },
59743
59744    /**
59745     * Returns CSS rules for a given SVG document
59746     * @static
59747     * @function
59748     * @memberOf fabric
59749     * @param {SVGDocument} doc SVG document to parse
59750     * @return {Object} CSS rules of this document
59751     */
59752    getCSSRules: function(doc) {
59753      var styles = doc.getElementsByTagName('style'), i, len,
59754          allRules = { }, rules;
59755
59756      // very crude parsing of style contents
59757      for (i = 0, len = styles.length; i < len; i++) {
59758        var styleContents = styles[i].textContent;
59759
59760        // remove comments
59761        styleContents = styleContents.replace(/\/\*[\s\S]*?\*\//g, '');
59762        if (styleContents.trim() === '') {
59763          continue;
59764        }
59765        rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g);
59766        rules = rules.map(function(rule) { return rule.trim(); });
59767        // eslint-disable-next-line no-loop-func
59768        rules.forEach(function(rule) {
59769
59770          var match = rule.match(/([\s\S]*?)\s*\{([^}]*)\}/),
59771              ruleObj = { }, declaration = match[2].trim(),
59772              propertyValuePairs = declaration.replace(/;$/, '').split(/\s*;\s*/);
59773
59774          for (i = 0, len = propertyValuePairs.length; i < len; i++) {
59775            var pair = propertyValuePairs[i].split(/\s*:\s*/),
59776                property = pair[0],
59777                value = pair[1];
59778            ruleObj[property] = value;
59779          }
59780          rule = match[1];
59781          rule.split(',').forEach(function(_rule) {
59782            _rule = _rule.replace(/^svg/i, '').trim();
59783            if (_rule === '') {
59784              return;
59785            }
59786            if (allRules[_rule]) {
59787              fabric.util.object.extend(allRules[_rule], ruleObj);
59788            }
59789            else {
59790              allRules[_rule] = fabric.util.object.clone(ruleObj);
59791            }
59792          });
59793        });
59794      }
59795      return allRules;
59796    },
59797
59798    /**
59799     * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.
59800     * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy)
59801     * @memberOf fabric
59802     * @param {String} url
59803     * @param {Function} callback
59804     * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
59805     * @param {Object} [options] Object containing options for parsing
59806     * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
59807     */
59808    loadSVGFromURL: function(url, callback, reviver, options) {
59809
59810      url = url.replace(/^\n\s*/, '').trim();
59811      new fabric.util.request(url, {
59812        method: 'get',
59813        onComplete: onComplete
59814      });
59815
59816      function onComplete(r) {
59817
59818        var xml = r.responseXML;
59819        if (!xml || !xml.documentElement) {
59820          callback && callback(null);
59821          return false;
59822        }
59823
59824        fabric.parseSVGDocument(xml.documentElement, function (results, _options, elements, allElements) {
59825          callback && callback(results, _options, elements, allElements);
59826        }, reviver, options);
59827      }
59828    },
59829
59830    /**
59831     * Takes string corresponding to an SVG document, and parses it into a set of fabric objects
59832     * @memberOf fabric
59833     * @param {String} string
59834     * @param {Function} callback
59835     * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
59836     * @param {Object} [options] Object containing options for parsing
59837     * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
59838     */
59839    loadSVGFromString: function(string, callback, reviver, options) {
59840      var parser = new fabric.window.DOMParser(),
59841          doc = parser.parseFromString(string.trim(), 'text/xml');
59842      fabric.parseSVGDocument(doc.documentElement, function (results, _options, elements, allElements) {
59843        callback(results, _options, elements, allElements);
59844      }, reviver, options);
59845    }
59846  });
59847
59848})( true ? exports : 
59848this
vendor: 12,776 bytes, lines 59848-60341
59848);
59849
59850
59851fabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions, doc) {
59852  this.elements = elements;
59853  this.callback = callback;
59854  this.options = options;
59855  this.reviver = reviver;
59856  this.svgUid = (options && options.svgUid) || 0;
59857  this.parsingOptions = parsingOptions;
59858  this.regexUrl = /^url\(['"]?#([^'"]+)['"]?\)/g;
59859  this.doc = doc;
59860};
59861
59862(function(proto) {
59863  proto.parse = function() {
59864    this.instances = new Array(this.elements.length);
59865    this.numElements = this.elements.length;
59866    this.createObjects();
59867  };
59868
59869  proto.createObjects = function() {
59870    var _this = this;
59871    this.elements.forEach(function(element, i) {
59872      element.setAttribute('svgUid', _this.svgUid);
59873      _this.createObject(element, i);
59874    });
59875  };
59876
59877  proto.findTag = function(el) {
59878    return fabric[fabric.util.string.capitalize(el.tagName.replace('svg:', ''))];
59879  };
59880
59881  proto.createObject = function(el, index) {
59882    var klass = this.findTag(el);
59883    if (klass && klass.fromElement) {
59884      try {
59885        klass.fromElement(el, this.createCallback(index, el), this.options);
59886      }
59887      catch (err) {
59888        fabric.log(err);
59889      }
59890    }
59891    else {
59892      this.checkIfDone();
59893    }
59894  };
59895
59896  proto.createCallback = function(index, el) {
59897    var _this = this;
59898    return function(obj) {
59899      var _options;
59900      _this.resolveGradient(obj, el, 'fill');
59901      _this.resolveGradient(obj, el, 'stroke');
59902      if (obj instanceof fabric.Image && obj._originalElement) {
59903        _options = obj.parsePreserveAspectRatioAttribute(el);
59904      }
59905      obj._removeTransformMatrix(_options);
59906      _this.resolveClipPath(obj, el);
59907      _this.reviver && _this.reviver(el, obj);
59908      _this.instances[index] = obj;
59909      _this.checkIfDone();
59910    };
59911  };
59912
59913  proto.extractPropertyDefinition = function(obj, property, storage) {
59914    var value = obj[property], regex = this.regexUrl;
59915    if (!regex.test(value)) {
59916      return;
59917    }
59918    regex.lastIndex = 0;
59919    var id = regex.exec(value)[1];
59920    regex.lastIndex = 0;
59921    return fabric[storage][this.svgUid][id];
59922  };
59923
59924  proto.resolveGradient = function(obj, el, property) {
59925    var gradientDef = this.extractPropertyDefinition(obj, property, 'gradientDefs');
59926    if (gradientDef) {
59927      var opacityAttr = el.getAttribute(property + '-opacity');
59928      var gradient = fabric.Gradient.fromElement(gradientDef, obj, opacityAttr, this.options);
59929      obj.set(property, gradient);
59930    }
59931  };
59932
59933  proto.createClipPathCallback = function(obj, container) {
59934    return function(_newObj) {
59935      _newObj._removeTransformMatrix();
59936      _newObj.fillRule = _newObj.clipRule;
59937      container.push(_newObj);
59938    };
59939  };
59940
59941  proto.resolveClipPath = function(obj, usingElement) {
59942    var clipPath = this.extractPropertyDefinition(obj, 'clipPath', 'clipPaths'),
59943        element, klass, objTransformInv, container, gTransform, options;
59944    if (clipPath) {
59945      container = [];
59946      objTransformInv = fabric.util.invertTransform(obj.calcTransformMatrix());
59947      // move the clipPath tag as sibling to the real element that is using it
59948      var clipPathTag = clipPath[0].parentNode;
59949      var clipPathOwner = usingElement;
59950      while (clipPathOwner.parentNode && clipPathOwner.getAttribute('clip-path') !== obj.clipPath) {
59951        clipPathOwner = clipPathOwner.parentNode;
59952      }
59953      clipPathOwner.parentNode.appendChild(clipPathTag);
59954      for (var i = 0; i < clipPath.length; i++) {
59955        element = clipPath[i];
59956        klass = this.findTag(element);
59957        klass.fromElement(
59958          element,
59959          this.createClipPathCallback(obj, container),
59960          this.options
59961        );
59962      }
59963      if (container.length === 1) {
59964        clipPath = container[0];
59965      }
59966      else {
59967        clipPath = new fabric.Group(container);
59968      }
59969      gTransform = fabric.util.multiplyTransformMatrices(
59970        objTransformInv,
59971        clipPath.calcTransformMatrix()
59972      );
59973      if (clipPath.clipPath) {
59974        this.resolveClipPath(clipPath, clipPathOwner);
59975      }
59976      var options = fabric.util.qrDecompose(gTransform);
59977      clipPath.flipX = false;
59978      clipPath.flipY = false;
59979      clipPath.set('scaleX', options.scaleX);
59980      clipPath.set('scaleY', options.scaleY);
59981      clipPath.angle = options.angle;
59982      clipPath.skewX = options.skewX;
59983      clipPath.skewY = 0;
59984      clipPath.setPositionByOrigin({ x: options.translateX, y: options.translateY }, 'center', 'center');
59985      obj.clipPath = clipPath;
59986    }
59987    else {
59988      // if clip-path does not resolve to any element, delete the property.
59989      delete obj.clipPath;
59990    }
59991  };
59992
59993  proto.checkIfDone = function() {
59994    if (--this.numElements === 0) {
59995      this.instances = this.instances.filter(function(el) {
59996        // eslint-disable-next-line no-eq-null, eqeqeq
59997        return el != null;
59998      });
59999      this.callback(this.instances, this.elements);
60000    }
60001  };
60002})(fabric.ElementsParser.prototype);
60003
60004
60005(function(global) {
60006
60007  'use strict';
60008
60009  /* Adaptation of work of Kevin Lindsey ([email protected]) */
60010
60011  var fabric = global.fabric || (global.fabric = { });
60012
60013  if (fabric.Point) {
60014    fabric.warn('fabric.Point is already defined');
60015    return;
60016  }
60017
60018  fabric.Point = Point;
60019
60020  /**
60021   * Point class
60022   * @class fabric.Point
60023   * @memberOf fabric
60024   * @constructor
60025   * @param {Number} x
60026   * @param {Number} y
60027   * @return {fabric.Point} thisArg
60028   */
60029  function Point(x, y) {
60030    this.x = x;
60031    this.y = y;
60032  }
60033
60034  Point.prototype = /** @lends fabric.Point.prototype */ {
60035
60036    type: 'point',
60037
60038    constructor: Point,
60039
60040    /**
60041     * Adds another point to this one and returns another one
60042     * @param {fabric.Point} that
60043     * @return {fabric.Point} new Point instance with added values
60044     */
60045    add: function (that) {
60046      return new Point(this.x + that.x, this.y + that.y);
60047    },
60048
60049    /**
60050     * Adds another point to this one
60051     * @param {fabric.Point} that
60052     * @return {fabric.Point} thisArg
60053     * @chainable
60054     */
60055    addEquals: function (that) {
60056      this.x += that.x;
60057      this.y += that.y;
60058      return this;
60059    },
60060
60061    /**
60062     * Adds value to this point and returns a new one
60063     * @param {Number} scalar
60064     * @return {fabric.Point} new Point with added value
60065     */
60066    scalarAdd: function (scalar) {
60067      return new Point(this.x + scalar, this.y + scalar);
60068    },
60069
60070    /**
60071     * Adds value to this point
60072     * @param {Number} scalar
60073     * @return {fabric.Point} thisArg
60074     * @chainable
60075     */
60076    scalarAddEquals: function (scalar) {
60077      this.x += scalar;
60078      this.y += scalar;
60079      return this;
60080    },
60081
60082    /**
60083     * Subtracts another point from this point and returns a new one
60084     * @param {fabric.Point} that
60085     * @return {fabric.Point} new Point object with subtracted values
60086     */
60087    subtract: function (that) {
60088      return new Point(this.x - that.x, this.y - that.y);
60089    },
60090
60091    /**
60092     * Subtracts another point from this point
60093     * @param {fabric.Point} that
60094     * @return {fabric.Point} thisArg
60095     * @chainable
60096     */
60097    subtractEquals: function (that) {
60098      this.x -= that.x;
60099      this.y -= that.y;
60100      return this;
60101    },
60102
60103    /**
60104     * Subtracts value from this point and returns a new one
60105     * @param {Number} scalar
60106     * @return {fabric.Point}
60107     */
60108    scalarSubtract: function (scalar) {
60109      return new Point(this.x - scalar, this.y - scalar);
60110    },
60111
60112    /**
60113     * Subtracts value from this point
60114     * @param {Number} scalar
60115     * @return {fabric.Point} thisArg
60116     * @chainable
60117     */
60118    scalarSubtractEquals: function (scalar) {
60119      this.x -= scalar;
60120      this.y -= scalar;
60121      return this;
60122    },
60123
60124    /**
60125     * Multiplies this point by a value and returns a new one
60126     * TODO: rename in scalarMultiply in 2.0
60127     * @param {Number} scalar
60128     * @return {fabric.Point}
60129     */
60130    multiply: function (scalar) {
60131      return new Point(this.x * scalar, this.y * scalar);
60132    },
60133
60134    /**
60135     * Multiplies this point by a value
60136     * TODO: rename in scalarMultiplyEquals in 2.0
60137     * @param {Number} scalar
60138     * @return {fabric.Point} thisArg
60139     * @chainable
60140     */
60141    multiplyEquals: function (scalar) {
60142      this.x *= scalar;
60143      this.y *= scalar;
60144      return this;
60145    },
60146
60147    /**
60148     * Divides this point by a value and returns a new one
60149     * TODO: rename in scalarDivide in 2.0
60150     * @param {Number} scalar
60151     * @return {fabric.Point}
60152     */
60153    divide: function (scalar) {
60154      return new Point(this.x / scalar, this.y / scalar);
60155    },
60156
60157    /**
60158     * Divides this point by a value
60159     * TODO: rename in scalarDivideEquals in 2.0
60160     * @param {Number} scalar
60161     * @return {fabric.Point} thisArg
60162     * @chainable
60163     */
60164    divideEquals: function (scalar) {
60165      this.x /= scalar;
60166      this.y /= scalar;
60167      return this;
60168    },
60169
60170    /**
60171     * Returns true if this point is equal to another one
60172     * @param {fabric.Point} that
60173     * @return {Boolean}
60174     */
60175    eq: function (that) {
60176      return (this.x === that.x && this.y === that.y);
60177    },
60178
60179    /**
60180     * Returns true if this point is less than another one
60181     * @param {fabric.Point} that
60182     * @return {Boolean}
60183     */
60184    lt: function (that) {
60185      return (this.x < that.x && this.y < that.y);
60186    },
60187
60188    /**
60189     * Returns true if this point is less than or equal to another one
60190     * @param {fabric.Point} that
60191     * @return {Boolean}
60192     */
60193    lte: function (that) {
60194      return (this.x <= that.x && this.y <= that.y);
60195    },
60196
60197    /**
60198
60199     * Returns true if this point is greater another one
60200     * @param {fabric.Point} that
60201     * @return {Boolean}
60202     */
60203    gt: function (that) {
60204      return (this.x > that.x && this.y > that.y);
60205    },
60206
60207    /**
60208     * Returns true if this point is greater than or equal to another one
60209     * @param {fabric.Point} that
60210     * @return {Boolean}
60211     */
60212    gte: function (that) {
60213      return (this.x >= that.x && this.y >= that.y);
60214    },
60215
60216    /**
60217     * Returns new point which is the result of linear interpolation with this one and another one
60218     * @param {fabric.Point} that
60219     * @param {Number} t , position of interpolation, between 0 and 1 default 0.5
60220     * @return {fabric.Point}
60221     */
60222    lerp: function (that, t) {
60223      if (typeof t === 'undefined') {
60224        t = 0.5;
60225      }
60226      t = Math.max(Math.min(1, t), 0);
60227      return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t);
60228    },
60229
60230    /**
60231     * Returns distance from this point and another one
60232     * @param {fabric.Point} that
60233     * @return {Number}
60234     */
60235    distanceFrom: function (that) {
60236      var dx = this.x - that.x,
60237          dy = this.y - that.y;
60238      return Math.sqrt(dx * dx + dy * dy);
60239    },
60240
60241    /**
60242     * Returns the point between this point and another one
60243     * @param {fabric.Point} that
60244     * @return {fabric.Point}
60245     */
60246    midPointFrom: function (that) {
60247      return this.lerp(that);
60248    },
60249
60250    /**
60251     * Returns a new point which is the min of this and another one
60252     * @param {fabric.Point} that
60253     * @return {fabric.Point}
60254     */
60255    min: function (that) {
60256      return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));
60257    },
60258
60259    /**
60260     * Returns a new point which is the max of this and another one
60261     * @param {fabric.Point} that
60262     * @return {fabric.Point}
60263     */
60264    max: function (that) {
60265      return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));
60266    },
60267
60268    /**
60269     * Returns string representation of this point
60270     * @return {String}
60271     */
60272    toString: function () {
60273      return this.x + ',' + this.y;
60274    },
60275
60276    /**
60277     * Sets x/y of this point
60278     * @param {Number} x
60279     * @param {Number} y
60280     * @chainable
60281     */
60282    setXY: function (x, y) {
60283      this.x = x;
60284      this.y = y;
60285      return this;
60286    },
60287
60288    /**
60289     * Sets x of this point
60290     * @param {Number} x
60291     * @chainable
60292     */
60293    setX: function (x) {
60294      this.x = x;
60295      return this;
60296    },
60297
60298    /**
60299     * Sets y of this point
60300     * @param {Number} y
60301     * @chainable
60302     */
60303    setY: function (y) {
60304      this.y = y;
60305      return this;
60306    },
60307
60308    /**
60309     * Sets x/y of this point from another point
60310     * @param {fabric.Point} that
60311     * @chainable
60312     */
60313    setFromPoint: function (that) {
60314      this.x = that.x;
60315      this.y = that.y;
60316      return this;
60317    },
60318
60319    /**
60320     * Swaps x/y of this point and another point
60321     * @param {fabric.Point} that
60322     */
60323    swap: function (that) {
60324      var x = this.x,
60325          y = this.y;
60326      this.x = that.x;
60327      this.y = that.y;
60328      that.x = x;
60329      that.y = y;
60330    },
60331
60332    /**
60333     * return a cloned instance of the point
60334     * @return {fabric.Point}
60335     */
60336    clone: function () {
60337      return new Point(this.x, this.y);
60338    }
60339  };
60340
60341})( true ? exports : 
vendor: 4,709 bytes, lines 60341-60515
60341this);
60342
60343
60344(function(global) {
60345
60346  'use strict';
60347
60348  /* Adaptation of work of Kevin Lindsey ([email protected]) */
60349  var fabric = global.fabric || (global.fabric = { });
60350
60351  if (fabric.Intersection) {
60352    fabric.warn('fabric.Intersection is already defined');
60353    return;
60354  }
60355
60356  /**
60357   * Intersection class
60358   * @class fabric.Intersection
60359   * @memberOf fabric
60360   * @constructor
60361   */
60362  function Intersection(status) {
60363    this.status = status;
60364    this.points = [];
60365  }
60366
60367  fabric.Intersection = Intersection;
60368
60369  fabric.Intersection.prototype = /** @lends fabric.Intersection.prototype */ {
60370
60371    constructor: Intersection,
60372
60373    /**
60374     * Appends a point to intersection
60375     * @param {fabric.Point} point
60376     * @return {fabric.Intersection} thisArg
60377     * @chainable
60378     */
60379    appendPoint: function (point) {
60380      this.points.push(point);
60381      return this;
60382    },
60383
60384    /**
60385     * Appends points to intersection
60386     * @param {Array} points
60387     * @return {fabric.Intersection} thisArg
60388     * @chainable
60389     */
60390    appendPoints: function (points) {
60391      this.points = this.points.concat(points);
60392      return this;
60393    }
60394  };
60395
60396  /**
60397   * Checks if one line intersects another
60398   * TODO: rename in intersectSegmentSegment
60399   * @static
60400   * @param {fabric.Point} a1
60401   * @param {fabric.Point} a2
60402   * @param {fabric.Point} b1
60403   * @param {fabric.Point} b2
60404   * @return {fabric.Intersection}
60405   */
60406  fabric.Intersection.intersectLineLine = function (a1, a2, b1, b2) {
60407    var result,
60408        uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x),
60409        ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x),
60410        uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);
60411    if (uB !== 0) {
60412      var ua = uaT / uB,
60413          ub = ubT / uB;
60414      if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {
60415        result = new Intersection('Intersection');
60416        result.appendPoint(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)));
60417      }
60418      else {
60419        result = new Intersection();
60420      }
60421    }
60422    else {
60423      if (uaT === 0 || ubT === 0) {
60424        result = new Intersection('Coincident');
60425      }
60426      else {
60427        result = new Intersection('Parallel');
60428      }
60429    }
60430    return result;
60431  };
60432
60433  /**
60434   * Checks if line intersects polygon
60435   * TODO: rename in intersectSegmentPolygon
60436   * fix detection of coincident
60437   * @static
60438   * @param {fabric.Point} a1
60439   * @param {fabric.Point} a2
60440   * @param {Array} points
60441   * @return {fabric.Intersection}
60442   */
60443  fabric.Intersection.intersectLinePolygon = function(a1, a2, points) {
60444    var result = new Intersection(),
60445        length = points.length,
60446        b1, b2, inter, i;
60447
60448    for (i = 0; i < length; i++) {
60449      b1 = points[i];
60450      b2 = points[(i + 1) % length];
60451      inter = Intersection.intersectLineLine(a1, a2, b1, b2);
60452
60453      result.appendPoints(inter.points);
60454    }
60455    if (result.points.length > 0) {
60456      result.status = 'Intersection';
60457    }
60458    return result;
60459  };
60460
60461  /**
60462   * Checks if polygon intersects another polygon
60463   * @static
60464   * @param {Array} points1
60465   * @param {Array} points2
60466   * @return {fabric.Intersection}
60467   */
60468  fabric.Intersection.intersectPolygonPolygon = function (points1, points2) {
60469    var result = new Intersection(),
60470        length = points1.length, i;
60471
60472    for (i = 0; i < length; i++) {
60473      var a1 = points1[i],
60474          a2 = points1[(i + 1) % length],
60475          inter = Intersection.intersectLinePolygon(a1, a2, points2);
60476
60477      result.appendPoints(inter.points);
60478    }
60479    if (result.points.length > 0) {
60480      result.status = 'Intersection';
60481    }
60482    return result;
60483  };
60484
60485  /**
60486   * Checks if polygon intersects rectangle
60487   * @static
60488   * @param {Array} points
60489   * @param {fabric.Point} r1
60490   * @param {fabric.Point} r2
60491   * @return {fabric.Intersection}
60492   */
60493  fabric.Intersection.intersectPolygonRectangle = function (points, r1, r2) {
60494    var min = r1.min(r2),
60495        max = r1.max(r2),
60496        topRight = new fabric.Point(max.x, min.y),
60497        bottomLeft = new fabric.Point(min.x, max.y),
60498        inter1 = Intersection.intersectLinePolygon(min, topRight, points),
60499        inter2 = Intersection.intersectLinePolygon(topRight, max, points),
60500        inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points),
60501        inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points),
60502        result = new Intersection();
60503
60504    result.appendPoints(inter1.points);
60505    result.appendPoints(inter2.points);
60506    result.appendPoints(inter3.points);
60507    result.appendPoints(inter4.points);
60508
60509    if (result.points.length > 0) {
60510      result.status = 'Intersection';
60511    }
60512    return result;
60513  };
60514
60515})( true ? exports : this
vendor: 19,349 bytes, lines 60515-61153
60515);
60516
60517
60518(function(global) {
60519
60520  'use strict';
60521
60522  var fabric = global.fabric || (global.fabric = { });
60523
60524  if (fabric.Color) {
60525    fabric.warn('fabric.Color is already defined.');
60526    return;
60527  }
60528
60529  /**
60530   * Color class
60531   * The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations;
60532   * {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects.
60533   *
60534   * @class fabric.Color
60535   * @param {String} color optional in hex or rgb(a) or hsl format or from known color list
60536   * @return {fabric.Color} thisArg
60537   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors}
60538   */
60539  function Color(color) {
60540    if (!color) {
60541      this.setSource([0, 0, 0, 1]);
60542    }
60543    else {
60544      this._tryParsingColor(color);
60545    }
60546  }
60547
60548  fabric.Color = Color;
60549
60550  fabric.Color.prototype = /** @lends fabric.Color.prototype */ {
60551
60552    /**
60553     * @private
60554     * @param {String|Array} color Color value to parse
60555     */
60556    _tryParsingColor: function(color) {
60557      var source;
60558
60559      if (color in Color.colorNameMap) {
60560        color = Color.colorNameMap[color];
60561      }
60562
60563      if (color === 'transparent') {
60564        source = [255, 255, 255, 0];
60565      }
60566
60567      if (!source) {
60568        source = Color.sourceFromHex(color);
60569      }
60570      if (!source) {
60571        source = Color.sourceFromRgb(color);
60572      }
60573      if (!source) {
60574        source = Color.sourceFromHsl(color);
60575      }
60576      if (!source) {
60577        //if color is not recognize let's make black as canvas does
60578        source = [0, 0, 0, 1];
60579      }
60580      if (source) {
60581        this.setSource(source);
60582      }
60583    },
60584
60585    /**
60586     * Adapted from <a href="https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html">https://github.com/mjijackson</a>
60587     * @private
60588     * @param {Number} r Red color value
60589     * @param {Number} g Green color value
60590     * @param {Number} b Blue color value
60591     * @return {Array} Hsl color
60592     */
60593    _rgbToHsl: function(r, g, b) {
60594      r /= 255; g /= 255; b /= 255;
60595
60596      var h, s, l,
60597          max = fabric.util.array.max([r, g, b]),
60598          min = fabric.util.array.min([r, g, b]);
60599
60600      l = (max + min) / 2;
60601
60602      if (max === min) {
60603        h = s = 0; // achromatic
60604      }
60605      else {
60606        var d = max - min;
60607        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
60608        switch (max) {
60609          case r:
60610            h = (g - b) / d + (g < b ? 6 : 0);
60611            break;
60612          case g:
60613            h = (b - r) / d + 2;
60614            break;
60615          case b:
60616            h = (r - g) / d + 4;
60617            break;
60618        }
60619        h /= 6;
60620      }
60621
60622      return [
60623        Math.round(h * 360),
60624        Math.round(s * 100),
60625        Math.round(l * 100)
60626      ];
60627    },
60628
60629    /**
60630     * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])
60631     * @return {Array}
60632     */
60633    getSource: function() {
60634      return this._source;
60635    },
60636
60637    /**
60638     * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])
60639     * @param {Array} source
60640     */
60641    setSource: function(source) {
60642      this._source = source;
60643    },
60644
60645    /**
60646     * Returns color representation in RGB format
60647     * @return {String} ex: rgb(0-255,0-255,0-255)
60648     */
60649    toRgb: function() {
60650      var source = this.getSource();
60651      return 'rgb(' + source[0] + ',' + source[1] + ',' + source[2] + ')';
60652    },
60653
60654    /**
60655     * Returns color representation in RGBA format
60656     * @return {String} ex: rgba(0-255,0-255,0-255,0-1)
60657     */
60658    toRgba: function() {
60659      var source = this.getSource();
60660      return 'rgba(' + source[0] + ',' + source[1] + ',' + source[2] + ',' + source[3] + ')';
60661    },
60662
60663    /**
60664     * Returns color representation in HSL format
60665     * @return {String} ex: hsl(0-360,0%-100%,0%-100%)
60666     */
60667    toHsl: function() {
60668      var source = this.getSource(),
60669          hsl = this._rgbToHsl(source[0], source[1], source[2]);
60670
60671      return 'hsl(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%)';
60672    },
60673
60674    /**
60675     * Returns color representation in HSLA format
60676     * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)
60677     */
60678    toHsla: function() {
60679      var source = this.getSource(),
60680          hsl = this._rgbToHsl(source[0], source[1], source[2]);
60681
60682      return 'hsla(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%,' + source[3] + ')';
60683    },
60684
60685    /**
60686     * Returns color representation in HEX format
60687     * @return {String} ex: FF5555
60688     */
60689    toHex: function() {
60690      var source = this.getSource(), r, g, b;
60691
60692      r = source[0].toString(16);
60693      r = (r.length === 1) ? ('0' + r) : r;
60694
60695      g = source[1].toString(16);
60696      g = (g.length === 1) ? ('0' + g) : g;
60697
60698      b = source[2].toString(16);
60699      b = (b.length === 1) ? ('0' + b) : b;
60700
60701      return r.toUpperCase() + g.toUpperCase() + b.toUpperCase();
60702    },
60703
60704    /**
60705     * Returns color representation in HEXA format
60706     * @return {String} ex: FF5555CC
60707     */
60708    toHexa: function() {
60709      var source = this.getSource(), a;
60710
60711      a = Math.round(source[3] * 255);
60712      a = a.toString(16);
60713      a = (a.length === 1) ? ('0' + a) : a;
60714
60715      return this.toHex() + a.toUpperCase();
60716    },
60717
60718    /**
60719     * Gets value of alpha channel for this color
60720     * @return {Number} 0-1
60721     */
60722    getAlpha: function() {
60723      return this.getSource()[3];
60724    },
60725
60726    /**
60727     * Sets value of alpha channel for this color
60728     * @param {Number} alpha Alpha value 0-1
60729     * @return {fabric.Color} thisArg
60730     */
60731    setAlpha: function(alpha) {
60732      var source = this.getSource();
60733      source[3] = alpha;
60734      this.setSource(source);
60735      return this;
60736    },
60737
60738    /**
60739     * Transforms color to its grayscale representation
60740     * @return {fabric.Color} thisArg
60741     */
60742    toGrayscale: function() {
60743      var source = this.getSource(),
60744          average = parseInt((source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), 10),
60745          currentAlpha = source[3];
60746      this.setSource([average, average, average, currentAlpha]);
60747      return this;
60748    },
60749
60750    /**
60751     * Transforms color to its black and white representation
60752     * @param {Number} threshold
60753     * @return {fabric.Color} thisArg
60754     */
60755    toBlackWhite: function(threshold) {
60756      var source = this.getSource(),
60757          average = (source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0),
60758          currentAlpha = source[3];
60759
60760      threshold = threshold || 127;
60761
60762      average = (Number(average) < Number(threshold)) ? 0 : 255;
60763      this.setSource([average, average, average, currentAlpha]);
60764      return this;
60765    },
60766
60767    /**
60768     * Overlays color with another color
60769     * @param {String|fabric.Color} otherColor
60770     * @return {fabric.Color} thisArg
60771     */
60772    overlayWith: function(otherColor) {
60773      if (!(otherColor instanceof Color)) {
60774        otherColor = new Color(otherColor);
60775      }
60776
60777      var result = [],
60778          alpha = this.getAlpha(),
60779          otherAlpha = 0.5,
60780          source = this.getSource(),
60781          otherSource = otherColor.getSource(), i;
60782
60783      for (i = 0; i < 3; i++) {
60784        result.push(Math.round((source[i] * (1 - otherAlpha)) + (otherSource[i] * otherAlpha)));
60785      }
60786
60787      result[3] = alpha;
60788      this.setSource(result);
60789      return this;
60790    }
60791  };
60792
60793  /**
60794   * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5))
60795   * @static
60796   * @field
60797   * @memberOf fabric.Color
60798   */
60799  // eslint-disable-next-line max-len
60800  fabric.Color.reRGBa = /^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*((?:\d*\.?\d+)?)\s*)?\)$/i;
60801
60802  /**
60803   * Regex matching color in HSL or HSLA formats (ex: hsl(200, 80%, 10%), hsla(300, 50%, 80%, 0.5), hsla( 300 , 50% , 80% , 0.5 ))
60804   * @static
60805   * @field
60806   * @memberOf fabric.Color
60807   */
60808  fabric.Color.reHSLa = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/i;
60809
60810  /**
60811   * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff)
60812   * @static
60813   * @field
60814   * @memberOf fabric.Color
60815   */
60816  fabric.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i;
60817
60818  /**
60819   * Map of the 148 color names with HEX code
60820   * @static
60821   * @field
60822   * @memberOf fabric.Color
60823   * @see: https://www.w3.org/TR/css3-color/#svg-color
60824   */
60825  fabric.Color.colorNameMap = {
60826    aliceblue:            '#F0F8FF',
60827    antiquewhite:         '#FAEBD7',
60828    aqua:                 '#00FFFF',
60829    aquamarine:           '#7FFFD4',
60830    azure:                '#F0FFFF',
60831    beige:                '#F5F5DC',
60832    bisque:               '#FFE4C4',
60833    black:                '#000000',
60834    blanchedalmond:       '#FFEBCD',
60835    blue:                 '#0000FF',
60836    blueviolet:           '#8A2BE2',
60837    brown:                '#A52A2A',
60838    burlywood:            '#DEB887',
60839    cadetblue:            '#5F9EA0',
60840    chartreuse:           '#7FFF00',
60841    chocolate:            '#D2691E',
60842    coral:                '#FF7F50',
60843    cornflowerblue:       '#6495ED',
60844    cornsilk:             '#FFF8DC',
60845    crimson:              '#DC143C',
60846    cyan:                 '#00FFFF',
60847    darkblue:             '#00008B',
60848    darkcyan:             '#008B8B',
60849    darkgoldenrod:        '#B8860B',
60850    darkgray:             '#A9A9A9',
60851    darkgrey:             '#A9A9A9',
60852    darkgreen:            '#006400',
60853    darkkhaki:            '#BDB76B',
60854    darkmagenta:          '#8B008B',
60855    darkolivegreen:       '#556B2F',
60856    darkorange:           '#FF8C00',
60857    darkorchid:           '#9932CC',
60858    darkred:              '#8B0000',
60859    darksalmon:           '#E9967A',
60860    darkseagreen:         '#8FBC8F',
60861    darkslateblue:        '#483D8B',
60862    darkslategray:        '#2F4F4F',
60863    darkslategrey:        '#2F4F4F',
60864    darkturquoise:        '#00CED1',
60865    darkviolet:           '#9400D3',
60866    deeppink:             '#FF1493',
60867    deepskyblue:          '#00BFFF',
60868    dimgray:              '#696969',
60869    dimgrey:              '#696969',
60870    dodgerblue:           '#1E90FF',
60871    firebrick:            '#B22222',
60872    floralwhite:          '#FFFAF0',
60873    forestgreen:          '#228B22',
60874    fuchsia:              '#FF00FF',
60875    gainsboro:            '#DCDCDC',
60876    ghostwhite:           '#F8F8FF',
60877    gold:                 '#FFD700',
60878    goldenrod:            '#DAA520',
60879    gray:                 '#808080',
60880    grey:                 '#808080',
60881    green:                '#008000',
60882    greenyellow:          '#ADFF2F',
60883    honeydew:             '#F0FFF0',
60884    hotpink:              '#FF69B4',
60885    indianred:            '#CD5C5C',
60886    indigo:               '#4B0082',
60887    ivory:                '#FFFFF0',
60888    khaki:                '#F0E68C',
60889    lavender:             '#E6E6FA',
60890    lavenderblush:        '#FFF0F5',
60891    lawngreen:            '#7CFC00',
60892    lemonchiffon:         '#FFFACD',
60893    lightblue:            '#ADD8E6',
60894    lightcoral:           '#F08080',
60895    lightcyan:            '#E0FFFF',
60896    lightgoldenrodyellow: '#FAFAD2',
60897    lightgray:            '#D3D3D3',
60898    lightgrey:            '#D3D3D3',
60899    lightgreen:           '#90EE90',
60900    lightpink:            '#FFB6C1',
60901    lightsalmon:          '#FFA07A',
60902    lightseagreen:        '#20B2AA',
60903    lightskyblue:         '#87CEFA',
60904    lightslategray:       '#778899',
60905    lightslategrey:       '#778899',
60906    lightsteelblue:       '#B0C4DE',
60907    lightyellow:          '#FFFFE0',
60908    lime:                 '#00FF00',
60909    limegreen:            '#32CD32',
60910    linen:                '#FAF0E6',
60911    magenta:              '#FF00FF',
60912    maroon:               '#800000',
60913    mediumaquamarine:     '#66CDAA',
60914    mediumblue:           '#0000CD',
60915    mediumorchid:         '#BA55D3',
60916    mediumpurple:         '#9370DB',
60917    mediumseagreen:       '#3CB371',
60918    mediumslateblue:      '#7B68EE',
60919    mediumspringgreen:    '#00FA9A',
60920    mediumturquoise:      '#48D1CC',
60921    mediumvioletred:      '#C71585',
60922    midnightblue:         '#191970',
60923    mintcream:            '#F5FFFA',
60924    mistyrose:            '#FFE4E1',
60925    moccasin:             '#FFE4B5',
60926    navajowhite:          '#FFDEAD',
60927    navy:                 '#000080',
60928    oldlace:              '#FDF5E6',
60929    olive:                '#808000',
60930    olivedrab:            '#6B8E23',
60931    orange:               '#FFA500',
60932    orangered:            '#FF4500',
60933    orchid:               '#DA70D6',
60934    palegoldenrod:        '#EEE8AA',
60935    palegreen:            '#98FB98',
60936    paleturquoise:        '#AFEEEE',
60937    palevioletred:        '#DB7093',
60938    papayawhip:           '#FFEFD5',
60939    peachpuff:            '#FFDAB9',
60940    peru:                 '#CD853F',
60941    pink:                 '#FFC0CB',
60942    plum:                 '#DDA0DD',
60943    powderblue:           '#B0E0E6',
60944    purple:               '#800080',
60945    rebeccapurple:        '#663399',
60946    red:                  '#FF0000',
60947    rosybrown:            '#BC8F8F',
60948    royalblue:            '#4169E1',
60949    saddlebrown:          '#8B4513',
60950    salmon:               '#FA8072',
60951    sandybrown:           '#F4A460',
60952    seagreen:             '#2E8B57',
60953    seashell:             '#FFF5EE',
60954    sienna:               '#A0522D',
60955    silver:               '#C0C0C0',
60956    skyblue:              '#87CEEB',
60957    slateblue:            '#6A5ACD',
60958    slategray:            '#708090',
60959    slategrey:            '#708090',
60960    snow:                 '#FFFAFA',
60961    springgreen:          '#00FF7F',
60962    steelblue:            '#4682B4',
60963    tan:                  '#D2B48C',
60964    teal:                 '#008080',
60965    thistle:              '#D8BFD8',
60966    tomato:               '#FF6347',
60967    turquoise:            '#40E0D0',
60968    violet:               '#EE82EE',
60969    wheat:                '#F5DEB3',
60970    white:                '#FFFFFF',
60971    whitesmoke:           '#F5F5F5',
60972    yellow:               '#FFFF00',
60973    yellowgreen:          '#9ACD32'
60974  };
60975
60976  /**
60977   * @private
60978   * @param {Number} p
60979   * @param {Number} q
60980   * @param {Number} t
60981   * @return {Number}
60982   */
60983  function hue2rgb(p, q, t) {
60984    if (t < 0) {
60985      t += 1;
60986    }
60987    if (t > 1) {
60988      t -= 1;
60989    }
60990    if (t < 1 / 6) {
60991      return p + (q - p) * 6 * t;
60992    }
60993    if (t < 1 / 2) {
60994      return q;
60995    }
60996    if (t < 2 / 3) {
60997      return p + (q - p) * (2 / 3 - t) * 6;
60998    }
60999    return p;
61000  }
61001
61002  /**
61003   * Returns new color object, when given a color in RGB format
61004   * @memberOf fabric.Color
61005   * @param {String} color Color value ex: rgb(0-255,0-255,0-255)
61006   * @return {fabric.Color}
61007   */
61008  fabric.Color.fromRgb = function(color) {
61009    return Color.fromSource(Color.sourceFromRgb(color));
61010  };
61011
61012  /**
61013   * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format
61014   * @memberOf fabric.Color
61015   * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)
61016   * @return {Array} source
61017   */
61018  fabric.Color.sourceFromRgb = function(color) {
61019    var match = color.match(Color.reRGBa);
61020    if (match) {
61021      var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1),
61022          g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1),
61023          b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1);
61024
61025      return [
61026        parseInt(r, 10),
61027        parseInt(g, 10),
61028        parseInt(b, 10),
61029        match[4] ? parseFloat(match[4]) : 1
61030      ];
61031    }
61032  };
61033
61034  /**
61035   * Returns new color object, when given a color in RGBA format
61036   * @static
61037   * @function
61038   * @memberOf fabric.Color
61039   * @param {String} color
61040   * @return {fabric.Color}
61041   */
61042  fabric.Color.fromRgba = Color.fromRgb;
61043
61044  /**
61045   * Returns new color object, when given a color in HSL format
61046   * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%)
61047   * @memberOf fabric.Color
61048   * @return {fabric.Color}
61049   */
61050  fabric.Color.fromHsl = function(color) {
61051    return Color.fromSource(Color.sourceFromHsl(color));
61052  };
61053
61054  /**
61055   * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.
61056   * Adapted from <a href="https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html">https://github.com/mjijackson</a>
61057   * @memberOf fabric.Color
61058   * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)
61059   * @return {Array} source
61060   * @see http://http://www.w3.org/TR/css3-color/#hsl-color
61061   */
61062  fabric.Color.sourceFromHsl = function(color) {
61063    var match = color.match(Color.reHSLa);
61064    if (!match) {
61065      return;
61066    }
61067
61068    var h = (((parseFloat(match[1]) % 360) + 360) % 360) / 360,
61069        s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1),
61070        l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1),
61071        r, g, b;
61072
61073    if (s === 0) {
61074      r = g = b = l;
61075    }
61076    else {
61077      var q = l <= 0.5 ? l * (s + 1) : l + s - l * s,
61078          p = l * 2 - q;
61079
61080      r = hue2rgb(p, q, h + 1 / 3);
61081      g = hue2rgb(p, q, h);
61082      b = hue2rgb(p, q, h - 1 / 3);
61083    }
61084
61085    return [
61086      Math.round(r * 255),
61087      Math.round(g * 255),
61088      Math.round(b * 255),
61089      match[4] ? parseFloat(match[4]) : 1
61090    ];
61091  };
61092
61093  /**
61094   * Returns new color object, when given a color in HSLA format
61095   * @static
61096   * @function
61097   * @memberOf fabric.Color
61098   * @param {String} color
61099   * @return {fabric.Color}
61100   */
61101  fabric.Color.fromHsla = Color.fromHsl;
61102
61103  /**
61104   * Returns new color object, when given a color in HEX format
61105   * @static
61106   * @memberOf fabric.Color
61107   * @param {String} color Color value ex: FF5555
61108   * @return {fabric.Color}
61109   */
61110  fabric.Color.fromHex = function(color) {
61111    return Color.fromSource(Color.sourceFromHex(color));
61112  };
61113
61114  /**
61115   * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format
61116   * @static
61117   * @memberOf fabric.Color
61118   * @param {String} color ex: FF5555 or FF5544CC (RGBa)
61119   * @return {Array} source
61120   */
61121  fabric.Color.sourceFromHex = function(color) {
61122    if (color.match(Color.reHex)) {
61123      var value = color.slice(color.indexOf('#') + 1),
61124          isShortNotation = (value.length === 3 || value.length === 4),
61125          isRGBa = (value.length === 8 || value.length === 4),
61126          r = isShortNotation ? (value.charAt(0) + value.charAt(0)) : value.substring(0, 2),
61127          g = isShortNotation ? (value.charAt(1) + value.charAt(1)) : value.substring(2, 4),
61128          b = isShortNotation ? (value.charAt(2) + value.charAt(2)) : value.substring(4, 6),
61129          a = isRGBa ? (isShortNotation ? (value.charAt(3) + value.charAt(3)) : value.substring(6, 8)) : 'FF';
61130
61131      return [
61132        parseInt(r, 16),
61133        parseInt(g, 16),
61134        parseInt(b, 16),
61135        parseFloat((parseInt(a, 16) / 255).toFixed(2))
61136      ];
61137    }
61138  };
61139
61140  /**
61141   * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5])
61142   * @static
61143   * @memberOf fabric.Color
61144   * @param {Array} source
61145   * @return {fabric.Color}
61146   */
61147  fabric.Color.fromSource = function(source) {
61148    var oColor = new Color();
61149    oColor.setSource(source);
61150    return oColor;
61151  };
61152
61153})( true ? exports : 
61153this
vendor: 29,990 bytes, lines 61153-61895
61153);
61154
61155
61156(function(global) {
61157
61158  'use strict';
61159
61160  var fabric = global.fabric || (global.fabric = { }),
61161      scaleMap = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'],
61162      skewMap = ['ns', 'nesw', 'ew', 'nwse'],
61163      controls = {},
61164      LEFT = 'left', TOP = 'top', RIGHT = 'right', BOTTOM = 'bottom', CENTER = 'center',
61165      opposite = {
61166        top: BOTTOM,
61167        bottom: TOP,
61168        left: RIGHT,
61169        right: LEFT,
61170        center: CENTER,
61171      }, radiansToDegrees = fabric.util.radiansToDegrees,
61172      sign = (Math.sign || function(x) { return ((x > 0) - (x < 0)) || +x; });
61173
61174  /**
61175   * Combine control position and object angle to find the control direction compared
61176   * to the object center.
61177   * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls
61178   * @param {fabric.Control} control the control class
61179   * @return {Number} 0 - 7 a quadrant number
61180   */
61181  function findCornerQuadrant(fabricObject, control) {
61182    var cornerAngle = fabricObject.angle + radiansToDegrees(Math.atan2(control.y, control.x)) + 360;
61183    return Math.round((cornerAngle % 360) / 45);
61184  }
61185
61186  function fireEvent(eventName, options) {
61187    var target = options.transform.target,
61188        canvas = target.canvas,
61189        canvasOptions = fabric.util.object.clone(options);
61190    canvasOptions.target = target;
61191    canvas && canvas.fire('object:' + eventName, canvasOptions);
61192    target.fire(eventName, options);
61193  }
61194
61195  /**
61196   * Inspect event and fabricObject properties to understand if the scaling action
61197   * @param {Event} eventData from the user action
61198   * @param {fabric.Object} fabricObject the fabric object about to scale
61199   * @return {Boolean} true if scale is proportional
61200   */
61201  function scaleIsProportional(eventData, fabricObject) {
61202    var canvas = fabricObject.canvas, uniScaleKey = canvas.uniScaleKey,
61203        uniformIsToggled = eventData[uniScaleKey];
61204    return (canvas.uniformScaling && !uniformIsToggled) ||
61205    (!canvas.uniformScaling && uniformIsToggled);
61206  }
61207
61208  /**
61209   * Checks if transform is centered
61210   * @param {Object} transform transform data
61211   * @return {Boolean} true if transform is centered
61212   */
61213  function isTransformCentered(transform) {
61214    return transform.originX === CENTER && transform.originY === CENTER;
61215  }
61216
61217  /**
61218   * Inspect fabricObject to understand if the current scaling action is allowed
61219   * @param {fabric.Object} fabricObject the fabric object about to scale
61220   * @param {String} by 'x' or 'y' or ''
61221   * @param {Boolean} scaleProportionally true if we are trying to scale proportionally
61222   * @return {Boolean} true if scaling is not allowed at current conditions
61223   */
61224  function scalingIsForbidden(fabricObject, by, scaleProportionally) {
61225    var lockX = fabricObject.lockScalingX, lockY = fabricObject.lockScalingY;
61226    if (lockX && lockY) {
61227      return true;
61228    }
61229    if (!by && (lockX || lockY) && scaleProportionally) {
61230      return true;
61231    }
61232    if (lockX && by === 'x') {
61233      return true;
61234    }
61235    if (lockY && by === 'y') {
61236      return true;
61237    }
61238    return false;
61239  }
61240
61241  /**
61242   * return the correct cursor style for the scale action
61243   * @param {Event} eventData the javascript event that is causing the scale
61244   * @param {fabric.Control} control the control that is interested in the action
61245   * @param {fabric.Object} fabricObject the fabric object that is interested in the action
61246   * @return {String} a valid css string for the cursor
61247   */
61248  function scaleCursorStyleHandler(eventData, control, fabricObject) {
61249    var notAllowed = 'not-allowed',
61250        scaleProportionally = scaleIsProportional(eventData, fabricObject),
61251        by = '';
61252    if (control.x !== 0 && control.y === 0) {
61253      by = 'x';
61254    }
61255    else if (control.x === 0 && control.y !== 0) {
61256      by = 'y';
61257    }
61258    if (scalingIsForbidden(fabricObject, by, scaleProportionally)) {
61259      return notAllowed;
61260    }
61261    var n = findCornerQuadrant(fabricObject, control);
61262    return scaleMap[n] + '-resize';
61263  }
61264
61265  /**
61266   * return the correct cursor style for the skew action
61267   * @param {Event} eventData the javascript event that is causing the scale
61268   * @param {fabric.Control} control the control that is interested in the action
61269   * @param {fabric.Object} fabricObject the fabric object that is interested in the action
61270   * @return {String} a valid css string for the cursor
61271   */
61272  function skewCursorStyleHandler(eventData, control, fabricObject) {
61273    var notAllowed = 'not-allowed';
61274    if (control.x !== 0 && fabricObject.lockSkewingY) {
61275      return notAllowed;
61276    }
61277    if (control.y !== 0 && fabricObject.lockSkewingX) {
61278      return notAllowed;
61279    }
61280    var n = findCornerQuadrant(fabricObject, control) % 4;
61281    return skewMap[n] + '-resize';
61282  }
61283
61284  /**
61285   * Combine skew and scale style handlers to cover fabric standard use case
61286   * @param {Event} eventData the javascript event that is causing the scale
61287   * @param {fabric.Control} control the control that is interested in the action
61288   * @param {fabric.Object} fabricObject the fabric object that is interested in the action
61289   * @return {String} a valid css string for the cursor
61290   */
61291  function scaleSkewCursorStyleHandler(eventData, control, fabricObject) {
61292    if (eventData[fabricObject.canvas.altActionKey]) {
61293      return controls.skewCursorStyleHandler(eventData, control, fabricObject);
61294    }
61295    return controls.scaleCursorStyleHandler(eventData, control, fabricObject);
61296  }
61297
61298  /**
61299   * Inspect event, control and fabricObject to return the correct action name
61300   * @param {Event} eventData the javascript event that is causing the scale
61301   * @param {fabric.Control} control the control that is interested in the action
61302   * @param {fabric.Object} fabricObject the fabric object that is interested in the action
61303   * @return {String} an action name
61304   */
61305  function scaleOrSkewActionName(eventData, control, fabricObject) {
61306    var isAlternative = eventData[fabricObject.canvas.altActionKey];
61307    if (control.x === 0) {
61308      // then is scaleY or skewX
61309      return isAlternative ? 'skewX' : 'scaleY';
61310    }
61311    if (control.y === 0) {
61312      // then is scaleY or skewX
61313      return isAlternative ? 'skewY' : 'scaleX';
61314    }
61315  }
61316
61317  /**
61318   * Find the correct style for the control that is used for rotation.
61319   * this function is very simple and it just take care of not-allowed or standard cursor
61320   * @param {Event} eventData the javascript event that is causing the scale
61321   * @param {fabric.Control} control the control that is interested in the action
61322   * @param {fabric.Object} fabricObject the fabric object that is interested in the action
61323   * @return {String} a valid css string for the cursor
61324   */
61325  function rotationStyleHandler(eventData, control, fabricObject) {
61326    if (fabricObject.lockRotation) {
61327      return 'not-allowed';
61328    }
61329    return control.cursorStyle;
61330  }
61331
61332  function commonEventInfo(eventData, transform, x, y) {
61333    return {
61334      e: eventData,
61335      transform: transform,
61336      pointer: {
61337        x: x,
61338        y: y,
61339      }
61340    };
61341  }
61342
61343  /**
61344   * Wrap an action handler with saving/restoring object position on the transform.
61345   * this is the code that permits to objects to keep their position while transforming.
61346   * @param {Function} actionHandler the function to wrap
61347   * @return {Function} a function with an action handler signature
61348   */
61349  function wrapWithFixedAnchor(actionHandler) {
61350    return function(eventData, transform, x, y) {
61351      var target = transform.target, centerPoint = target.getCenterPoint(),
61352          constraint = target.translateToOriginPoint(centerPoint, transform.originX, transform.originY),
61353          actionPerformed = actionHandler(eventData, transform, x, y);
61354      target.setPositionByOrigin(constraint, transform.originX, transform.originY);
61355      return actionPerformed;
61356    };
61357  }
61358
61359  /**
61360   * Wrap an action handler with firing an event if the action is performed
61361   * @param {Function} actionHandler the function to wrap
61362   * @return {Function} a function with an action handler signature
61363   */
61364  function wrapWithFireEvent(eventName, actionHandler) {
61365    return function(eventData, transform, x, y) {
61366      var actionPerformed = actionHandler(eventData, transform, x, y);
61367      if (actionPerformed) {
61368        fireEvent(eventName, commonEventInfo(eventData, transform, x, y));
61369      }
61370      return actionPerformed;
61371    };
61372  }
61373
61374  /**
61375   * Transforms a point described by x and y in a distance from the top left corner of the object
61376   * bounding box.
61377   * @param {Object} transform
61378   * @param {String} originX
61379   * @param {String} originY
61380   * @param {number} x
61381   * @param {number} y
61382   * @return {Fabric.Point} the normalized point
61383   */
61384  function getLocalPoint(transform, originX, originY, x, y) {
61385    var target = transform.target,
61386        control = target.controls[transform.corner],
61387        zoom = target.canvas.getZoom(),
61388        padding = target.padding / zoom,
61389        localPoint = target.toLocalPoint(new fabric.Point(x, y), originX, originY);
61390    if (localPoint.x >= padding) {
61391      localPoint.x -= padding;
61392    }
61393    if (localPoint.x <= -padding) {
61394      localPoint.x += padding;
61395    }
61396    if (localPoint.y >= padding) {
61397      localPoint.y -= padding;
61398    }
61399    if (localPoint.y <= padding) {
61400      localPoint.y += padding;
61401    }
61402    localPoint.x -= control.offsetX;
61403    localPoint.y -= control.offsetY;
61404    return localPoint;
61405  }
61406
61407  /**
61408   * Detect if the fabric object is flipped on one side.
61409   * @param {fabric.Object} target
61410   * @return {Boolean} true if one flip, but not two.
61411   */
61412  function targetHasOneFlip(target) {
61413    return target.flipX !== target.flipY;
61414  }
61415
61416  /**
61417   * Utility function to compensate the scale factor when skew is applied on both axes
61418   * @private
61419   */
61420  function compensateScaleForSkew(target, oppositeSkew, scaleToCompensate, axis, reference) {
61421    if (target[oppositeSkew] !== 0) {
61422      var newDim = target._getTransformedDimensions()[axis];
61423      var newValue = reference / newDim * target[scaleToCompensate];
61424      target.set(scaleToCompensate, newValue);
61425    }
61426  }
61427
61428  /**
61429   * Action handler for skewing on the X axis
61430   * @private
61431   */
61432  function skewObjectX(eventData, transform, x, y) {
61433    var target = transform.target,
61434        // find how big the object would be, if there was no skewX. takes in account scaling
61435        dimNoSkew = target._getTransformedDimensions(0, target.skewY),
61436        localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),
61437        // the mouse is in the center of the object, and we want it to stay there.
61438        // so the object will grow twice as much as the mouse.
61439        // this makes the skew growth to localPoint * 2 - dimNoSkew.
61440        totalSkewSize = Math.abs(localPoint.x * 2) - dimNoSkew.x,
61441        currentSkew = target.skewX, newSkew;
61442    if (totalSkewSize < 2) {
61443      // let's make it easy to go back to position 0.
61444      newSkew = 0;
61445    }
61446    else {
61447      newSkew = radiansToDegrees(
61448        Math.atan2((totalSkewSize / target.scaleX), (dimNoSkew.y / target.scaleY))
61449      );
61450      // now we have to find the sign of the skew.
61451      // it mostly depend on the origin of transformation.
61452      if (transform.originX === LEFT && transform.originY === BOTTOM) {
61453        newSkew = -newSkew;
61454      }
61455      if (transform.originX === RIGHT && transform.originY === TOP) {
61456        newSkew = -newSkew;
61457      }
61458      if (targetHasOneFlip(target)) {
61459        newSkew = -newSkew;
61460      }
61461    }
61462    var hasSkewed = currentSkew !== newSkew;
61463    if (hasSkewed) {
61464      var dimBeforeSkewing = target._getTransformedDimensions().y;
61465      target.set('skewX', newSkew);
61466      compensateScaleForSkew(target, 'skewY', 'scaleY', 'y', dimBeforeSkewing);
61467    }
61468    return hasSkewed;
61469  }
61470
61471  /**
61472   * Action handler for skewing on the Y axis
61473   * @private
61474   */
61475  function skewObjectY(eventData, transform, x, y) {
61476    var target = transform.target,
61477        // find how big the object would be, if there was no skewX. takes in account scaling
61478        dimNoSkew = target._getTransformedDimensions(target.skewX, 0),
61479        localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),
61480        // the mouse is in the center of the object, and we want it to stay there.
61481        // so the object will grow twice as much as the mouse.
61482        // this makes the skew growth to localPoint * 2 - dimNoSkew.
61483        totalSkewSize = Math.abs(localPoint.y * 2) - dimNoSkew.y,
61484        currentSkew = target.skewY, newSkew;
61485    if (totalSkewSize < 2) {
61486      // let's make it easy to go back to position 0.
61487      newSkew = 0;
61488    }
61489    else {
61490      newSkew = radiansToDegrees(
61491        Math.atan2((totalSkewSize / target.scaleY), (dimNoSkew.x / target.scaleX))
61492      );
61493      // now we have to find the sign of the skew.
61494      // it mostly depend on the origin of transformation.
61495      if (transform.originX === LEFT && transform.originY === BOTTOM) {
61496        newSkew = -newSkew;
61497      }
61498      if (transform.originX === RIGHT && transform.originY === TOP) {
61499        newSkew = -newSkew;
61500      }
61501      if (targetHasOneFlip(target)) {
61502        newSkew = -newSkew;
61503      }
61504    }
61505    var hasSkewed = currentSkew !== newSkew;
61506    if (hasSkewed) {
61507      var dimBeforeSkewing = target._getTransformedDimensions().x;
61508      target.set('skewY', newSkew);
61509      compensateScaleForSkew(target, 'skewX', 'scaleX', 'x', dimBeforeSkewing);
61510    }
61511    return hasSkewed;
61512  }
61513
61514  /**
61515   * Wrapped Action handler for skewing on the Y axis, takes care of the
61516   * skew direction and determine the correct transform origin for the anchor point
61517   * @param {Event} eventData javascript event that is doing the transform
61518   * @param {Object} transform javascript object containing a series of information around the current transform
61519   * @param {number} x current mouse x position, canvas normalized
61520   * @param {number} y current mouse y position, canvas normalized
61521   * @return {Boolean} true if some change happened
61522   */
61523  function skewHandlerX(eventData, transform, x, y) {
61524    // step1 figure out and change transform origin.
61525    // if skewX > 0 and originY bottom we anchor on right
61526    // if skewX > 0 and originY top we anchor on left
61527    // if skewX < 0 and originY bottom we anchor on left
61528    // if skewX < 0 and originY top we anchor on right
61529    // if skewX is 0, we look for mouse position to understand where are we going.
61530    var target = transform.target, currentSkew = target.skewX, originX, originY = transform.originY;
61531    if (target.lockSkewingX) {
61532      return false;
61533    }
61534    if (currentSkew === 0) {
61535      var localPointFromCenter = getLocalPoint(transform, CENTER, CENTER, x, y);
61536      if (localPointFromCenter.x > 0) {
61537        // we are pulling right, anchor left;
61538        originX = LEFT;
61539      }
61540      else {
61541        // we are pulling right, anchor right
61542        originX = RIGHT;
61543      }
61544    }
61545    else {
61546      if (currentSkew > 0) {
61547        originX = originY === TOP ? LEFT : RIGHT;
61548      }
61549      if (currentSkew < 0) {
61550        originX = originY === TOP ? RIGHT : LEFT;
61551      }
61552      // is the object flipped on one side only? swap the origin.
61553      if (targetHasOneFlip(target)) {
61554        originX = originX === LEFT ? RIGHT : LEFT;
61555      }
61556    }
61557
61558    // once we have the origin, we find the anchor point
61559    transform.originX = originX;
61560    var finalHandler = wrapWithFireEvent('skewing', wrapWithFixedAnchor(skewObjectX));
61561    return finalHandler(eventData, transform, x, y);
61562  }
61563
61564  /**
61565   * Wrapped Action handler for skewing on the Y axis, takes care of the
61566   * skew direction and determine the correct transform origin for the anchor point
61567   * @param {Event} eventData javascript event that is doing the transform
61568   * @param {Object} transform javascript object containing a series of information around the current transform
61569   * @param {number} x current mouse x position, canvas normalized
61570   * @param {number} y current mouse y position, canvas normalized
61571   * @return {Boolean} true if some change happened
61572   */
61573  function skewHandlerY(eventData, transform, x, y) {
61574    // step1 figure out and change transform origin.
61575    // if skewY > 0 and originX left we anchor on top
61576    // if skewY > 0 and originX right we anchor on bottom
61577    // if skewY < 0 and originX left we anchor on bottom
61578    // if skewY < 0 and originX right we anchor on top
61579    // if skewY is 0, we look for mouse position to understand where are we going.
61580    var target = transform.target, currentSkew = target.skewY, originY, originX = transform.originX;
61581    if (target.lockSkewingY) {
61582      return false;
61583    }
61584    if (currentSkew === 0) {
61585      var localPointFromCenter = getLocalPoint(transform, CENTER, CENTER, x, y);
61586      if (localPointFromCenter.y > 0) {
61587        // we are pulling down, anchor up;
61588        originY = TOP;
61589      }
61590      else {
61591        // we are pulling up, anchor down
61592        originY = BOTTOM;
61593      }
61594    }
61595    else {
61596      if (currentSkew > 0) {
61597        originY = originX === LEFT ? TOP : BOTTOM;
61598      }
61599      if (currentSkew < 0) {
61600        originY = originX === LEFT ? BOTTOM : TOP;
61601      }
61602      // is the object flipped on one side only? swap the origin.
61603      if (targetHasOneFlip(target)) {
61604        originY = originY === TOP ? BOTTOM : TOP;
61605      }
61606    }
61607
61608    // once we have the origin, we find the anchor point
61609    transform.originY = originY;
61610    var finalHandler = wrapWithFireEvent('skewing', wrapWithFixedAnchor(skewObjectY));
61611    return finalHandler(eventData, transform, x, y);
61612  }
61613
61614  /**
61615   * Action handler for rotation and snapping, without anchor point.
61616   * Needs to be wrapped with `wrapWithFixedAnchor` to be effective
61617   * @param {Event} eventData javascript event that is doing the transform
61618   * @param {Object} transform javascript object containing a series of information around the current transform
61619   * @param {number} x current mouse x position, canvas normalized
61620   * @param {number} y current mouse y position, canvas normalized
61621   * @return {Boolean} true if some change happened
61622   * @private
61623   */
61624  function rotationWithSnapping(eventData, transform, x, y) {
61625    var t = transform,
61626        target = t.target,
61627        pivotPoint = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY);
61628
61629    if (target.lockRotation) {
61630      return false;
61631    }
61632
61633    var lastAngle = Math.atan2(t.ey - pivotPoint.y, t.ex - pivotPoint.x),
61634        curAngle = Math.atan2(y - pivotPoint.y, x - pivotPoint.x),
61635        angle = radiansToDegrees(curAngle - lastAngle + t.theta),
61636        hasRotated = true;
61637
61638    if (target.snapAngle > 0) {
61639      var snapAngle  = target.snapAngle,
61640          snapThreshold  = target.snapThreshold || snapAngle,
61641          rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,
61642          leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;
61643
61644      if (Math.abs(angle - leftAngleLocked) < snapThreshold) {
61645        angle = leftAngleLocked;
61646      }
61647      else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {
61648        angle = rightAngleLocked;
61649      }
61650    }
61651
61652    // normalize angle to positive value
61653    if (angle < 0) {
61654      angle = 360 + angle;
61655    }
61656    angle %= 360;
61657
61658    hasRotated = target.angle !== angle;
61659    target.angle = angle;
61660    return hasRotated;
61661  }
61662
61663  /**
61664   * Basic scaling logic, reused with different constrain for scaling X,Y, freely or equally.
61665   * Needs to be wrapped with `wrapWithFixedAnchor` to be effective
61666   * @param {Event} eventData javascript event that is doing the transform
61667   * @param {Object} transform javascript object containing a series of information around the current transform
61668   * @param {number} x current mouse x position, canvas normalized
61669   * @param {number} y current mouse y position, canvas normalized
61670   * @param {Object} options additional information for scaling
61671   * @param {String} options.by 'x', 'y', 'equally' or '' to indicate type of scaling
61672   * @return {Boolean} true if some change happened
61673   * @private
61674   */
61675  function scaleObject(eventData, transform, x, y, options) {
61676    options = options || {};
61677    var target = transform.target,
61678        lockScalingX = target.lockScalingX, lockScalingY = target.lockScalingY,
61679        by = options.by, newPoint, scaleX, scaleY, dim,
61680        scaleProportionally = scaleIsProportional(eventData, target),
61681        forbidScaling = scalingIsForbidden(target, by, scaleProportionally),
61682        signX, signY, gestureScale = transform.gestureScale;
61683
61684    if (forbidScaling) {
61685      return false;
61686    }
61687    if (gestureScale) {
61688      scaleX = transform.scaleX * gestureScale;
61689      scaleY = transform.scaleY * gestureScale;
61690    }
61691    else {
61692      newPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y);
61693      // use of sign: We use sign to detect change of direction of an action. sign usually change when
61694      // we cross the origin point with the mouse. So a scale flip for example. There is an issue when scaling
61695      // by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily
61696      // cross many time the origin point and flip the object. so we need a way to filter out the noise.
61697      // This ternary here should be ok to filter out X scaling when we want Y only and vice versa.
61698      signX = by !== 'y' ? sign(newPoint.x) : 1;
61699      signY = by !== 'x' ? sign(newPoint.y) : 1;
61700      if (!transform.signX) {
61701        transform.signX = signX;
61702      }
61703      if (!transform.signY) {
61704        transform.signY = signY;
61705      }
61706
61707      if (target.lockScalingFlip &&
61708        (transform.signX !== signX || transform.signY !== signY)
61709      ) {
61710        return false;
61711      }
61712
61713      dim = target._getTransformedDimensions();
61714      // missing detection of flip and logic to switch the origin
61715      if (scaleProportionally && !by) {
61716        // uniform scaling
61717        var distance = Math.abs(newPoint.x) + Math.abs(newPoint.y),
61718            original = transform.original,
61719            originalDistance = Math.abs(dim.x * original.scaleX / target.scaleX) +
61720              Math.abs(dim.y * original.scaleY / target.scaleY),
61721            scale = distance / originalDistance;
61722        scaleX = original.scaleX * scale;
61723        scaleY = original.scaleY * scale;
61724      }
61725      else {
61726        scaleX = Math.abs(newPoint.x * target.scaleX / dim.x);
61727        scaleY = Math.abs(newPoint.y * target.scaleY / dim.y);
61728      }
61729      // if we are scaling by center, we need to double the scale
61730      if (isTransformCentered(transform)) {
61731        scaleX *= 2;
61732        scaleY *= 2;
61733      }
61734      if (transform.signX !== signX && by !== 'y') {
61735        transform.originX = opposite[transform.originX];
61736        scaleX *= -1;
61737        transform.signX = signX;
61738      }
61739      if (transform.signY !== signY && by !== 'x') {
61740        transform.originY = opposite[transform.originY];
61741        scaleY *= -1;
61742        transform.signY = signY;
61743      }
61744    }
61745    // minScale is taken are in the setter.
61746    var oldScaleX = target.scaleX, oldScaleY = target.scaleY;
61747    if (!by) {
61748      !lockScalingX && target.set('scaleX', scaleX);
61749      !lockScalingY && target.set('scaleY', scaleY);
61750    }
61751    else {
61752      // forbidden cases already handled on top here.
61753      by === 'x' && target.set('scaleX', scaleX);
61754      by === 'y' && target.set('scaleY', scaleY);
61755    }
61756    return oldScaleX !== target.scaleX || oldScaleY !== target.scaleY;
61757  }
61758
61759  /**
61760   * Generic scaling logic, to scale from corners either equally or freely.
61761   * Needs to be wrapped with `wrapWithFixedAnchor` to be effective
61762   * @param {Event} eventData javascript event that is doing the transform
61763   * @param {Object} transform javascript object containing a series of information around the current transform
61764   * @param {number} x current mouse x position, canvas normalized
61765   * @param {number} y current mouse y position, canvas normalized
61766   * @return {Boolean} true if some change happened
61767   */
61768  function scaleObjectFromCorner(eventData, transform, x, y) {
61769    return scaleObject(eventData, transform, x, y);
61770  }
61771
61772  /**
61773   * Scaling logic for the X axis.
61774   * Needs to be wrapped with `wrapWithFixedAnchor` to be effective
61775   * @param {Event} eventData javascript event that is doing the transform
61776   * @param {Object} transform javascript object containing a series of information around the current transform
61777   * @param {number} x current mouse x position, canvas normalized
61778   * @param {number} y current mouse y position, canvas normalized
61779   * @return {Boolean} true if some change happened
61780   */
61781  function scaleObjectX(eventData, transform, x, y) {
61782    return scaleObject(eventData, transform, x, y , { by: 'x' });
61783  }
61784
61785  /**
61786   * Scaling logic for the Y axis.
61787   * Needs to be wrapped with `wrapWithFixedAnchor` to be effective
61788   * @param {Event} eventData javascript event that is doing the transform
61789   * @param {Object} transform javascript object containing a series of information around the current transform
61790   * @param {number} x current mouse x position, canvas normalized
61791   * @param {number} y current mouse y position, canvas normalized
61792   * @return {Boolean} true if some change happened
61793   */
61794  function scaleObjectY(eventData, transform, x, y) {
61795    return scaleObject(eventData, transform, x, y , { by: 'y' });
61796  }
61797
61798  /**
61799   * Composed action handler to either scale Y or skew X
61800   * Needs to be wrapped with `wrapWithFixedAnchor` to be effective
61801   * @param {Event} eventData javascript event that is doing the transform
61802   * @param {Object} transform javascript object containing a series of information around the current transform
61803   * @param {number} x current mouse x position, canvas normalized
61804   * @param {number} y current mouse y position, canvas normalized
61805   * @return {Boolean} true if some change happened
61806   */
61807  function scalingYOrSkewingX(eventData, transform, x, y) {
61808    // ok some safety needed here.
61809    if (eventData[transform.target.canvas.altActionKey]) {
61810      return controls.skewHandlerX(eventData, transform, x, y);
61811    }
61812    return controls.scalingY(eventData, transform, x, y);
61813  }
61814
61815  /**
61816   * Composed action handler to either scale X or skew Y
61817   * Needs to be wrapped with `wrapWithFixedAnchor` to be effective
61818   * @param {Event} eventData javascript event that is doing the transform
61819   * @param {Object} transform javascript object containing a series of information around the current transform
61820   * @param {number} x current mouse x position, canvas normalized
61821   * @param {number} y current mouse y position, canvas normalized
61822   * @return {Boolean} true if some change happened
61823   */
61824  function scalingXOrSkewingY(eventData, transform, x, y) {
61825    // ok some safety needed here.
61826    if (eventData[transform.target.canvas.altActionKey]) {
61827      return controls.skewHandlerY(eventData, transform, x, y);
61828    }
61829    return controls.scalingX(eventData, transform, x, y);
61830  }
61831
61832  /**
61833   * Action handler to change textbox width
61834   * Needs to be wrapped with `wrapWithFixedAnchor` to be effective
61835   * @param {Event} eventData javascript event that is doing the transform
61836   * @param {Object} transform javascript object containing a series of information around the current transform
61837   * @param {number} x current mouse x position, canvas normalized
61838   * @param {number} y current mouse y position, canvas normalized
61839   * @return {Boolean} true if some change happened
61840   */
61841  function changeWidth(eventData, transform, x, y) {
61842    var target = transform.target, localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),
61843        strokePadding = target.strokeWidth / (target.strokeUniform ? target.scaleX : 1),
61844        multiplier = isTransformCentered(transform) ? 2 : 1,
61845        oldWidth = target.width,
61846        newWidth = Math.abs(localPoint.x * multiplier / target.scaleX) - strokePadding;
61847    target.set('width', Math.max(newWidth, 0));
61848    return oldWidth !== newWidth;
61849  }
61850
61851  /**
61852   * Action handler
61853   * @private
61854   * @param {Event} eventData javascript event that is doing the transform
61855   * @param {Object} transform javascript object containing a series of information around the current transform
61856   * @param {number} x current mouse x position, canvas normalized
61857   * @param {number} y current mouse y position, canvas normalized
61858   * @return {Boolean} true if the translation occurred
61859   */
61860  function dragHandler(eventData, transform, x, y) {
61861    var target = transform.target,
61862        newLeft = x - transform.offsetX,
61863        newTop = y - transform.offsetY,
61864        moveX = !target.get('lockMovementX') && target.left !== newLeft,
61865        moveY = !target.get('lockMovementY') && target.top !== newTop;
61866    moveX && target.set('left', newLeft);
61867    moveY && target.set('top', newTop);
61868    if (moveX || moveY) {
61869      fireEvent('moving', commonEventInfo(eventData, transform, x, y));
61870    }
61871    return moveX || moveY;
61872  }
61873
61874  controls.scaleCursorStyleHandler = scaleCursorStyleHandler;
61875  controls.skewCursorStyleHandler = skewCursorStyleHandler;
61876  controls.scaleSkewCursorStyleHandler = scaleSkewCursorStyleHandler;
61877  controls.rotationWithSnapping = wrapWithFireEvent('rotating', wrapWithFixedAnchor(rotationWithSnapping));
61878  controls.scalingEqually = wrapWithFireEvent('scaling', wrapWithFixedAnchor( scaleObjectFromCorner));
61879  controls.scalingX = wrapWithFireEvent('scaling', wrapWithFixedAnchor(scaleObjectX));
61880  controls.scalingY = wrapWithFireEvent('scaling', wrapWithFixedAnchor(scaleObjectY));
61881  controls.scalingYOrSkewingX = scalingYOrSkewingX;
61882  controls.scalingXOrSkewingY = scalingXOrSkewingY;
61883  controls.changeWidth = wrapWithFireEvent('resizing', wrapWithFixedAnchor(changeWidth));
61884  controls.skewHandlerX = skewHandlerX;
61885  controls.skewHandlerY = skewHandlerY;
61886  controls.dragHandler = dragHandler;
61887  controls.scaleOrSkewActionName = scaleOrSkewActionName;
61888  controls.rotationStyleHandler = rotationStyleHandler;
61889  controls.fireEvent = fireEvent;
61890  controls.wrapWithFixedAnchor = wrapWithFixedAnchor;
61891  controls.wrapWithFireEvent = wrapWithFireEvent;
61892  controls.getLocalPoint = getLocalPoint;
61893  fabric.controlsUtils = controls;
61894
61895})( true ? exports : 
vendor: 4,417 bytes, lines 61895-61996
61895this);
61896
61897
61898(function(global) {
61899
61900  'use strict';
61901
61902  var fabric = global.fabric || (global.fabric = { }),
61903      degreesToRadians = fabric.util.degreesToRadians,
61904      controls = fabric.controlsUtils;
61905
61906  /**
61907   * Render a round control, as per fabric features.
61908   * This function is written to respect object properties like transparentCorners, cornerSize
61909   * cornerColor, cornerStrokeColor
61910   * plus the addition of offsetY and offsetX.
61911   * @param {CanvasRenderingContext2D} ctx context to render on
61912   * @param {Number} left x coordinate where the control center should be
61913   * @param {Number} top y coordinate where the control center should be
61914   * @param {Object} styleOverride override for fabric.Object controls style
61915   * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls
61916   */
61917  function renderCircleControl (ctx, left, top, styleOverride, fabricObject) {
61918    styleOverride = styleOverride || {};
61919    var xSize = this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,
61920        ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,
61921        transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ?
61922          styleOverride.transparentCorners : fabricObject.transparentCorners,
61923        methodName = transparentCorners ? 'stroke' : 'fill',
61924        stroke = !transparentCorners && (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor),
61925        myLeft = left,
61926        myTop = top, size;
61927    ctx.save();
61928    ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor;
61929    ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor;
61930    // as soon as fabric react v5, remove ie11, use proper ellipse code.
61931    if (xSize > ySize) {
61932      size = xSize;
61933      ctx.scale(1.0, ySize / xSize);
61934      myTop = top * xSize / ySize;
61935    }
61936    else if (ySize > xSize) {
61937      size = ySize;
61938      ctx.scale(xSize / ySize, 1.0);
61939      myLeft = left * ySize / xSize;
61940    }
61941    else {
61942      size = xSize;
61943    }
61944    // this is still wrong
61945    ctx.lineWidth = 1;
61946    ctx.beginPath();
61947    ctx.arc(myLeft, myTop, size / 2, 0, 2 * Math.PI, false);
61948    ctx[methodName]();
61949    if (stroke) {
61950      ctx.stroke();
61951    }
61952    ctx.restore();
61953  }
61954
61955  /**
61956   * Render a square control, as per fabric features.
61957   * This function is written to respect object properties like transparentCorners, cornerSize
61958   * cornerColor, cornerStrokeColor
61959   * plus the addition of offsetY and offsetX.
61960   * @param {CanvasRenderingContext2D} ctx context to render on
61961   * @param {Number} left x coordinate where the control center should be
61962   * @param {Number} top y coordinate where the control center should be
61963   * @param {Object} styleOverride override for fabric.Object controls style
61964   * @param {fabric.Object} fabricObject the fabric object for which we are rendering controls
61965   */
61966  function renderSquareControl(ctx, left, top, styleOverride, fabricObject) {
61967    styleOverride = styleOverride || {};
61968    var xSize = this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,
61969        ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,
61970        transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ?
61971          styleOverride.transparentCorners : fabricObject.transparentCorners,
61972        methodName = transparentCorners ? 'stroke' : 'fill',
61973        stroke = !transparentCorners && (
61974          styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor
61975        ), xSizeBy2 = xSize / 2, ySizeBy2 = ySize / 2;
61976    ctx.save();
61977    ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor;
61978    ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor;
61979    // this is still wrong
61980    ctx.lineWidth = 1;
61981    ctx.translate(left, top);
61982    ctx.rotate(degreesToRadians(fabricObject.angle));
61983    // this does not work, and fixed with ( && ) does not make sense.
61984    // to have real transparent corners we need the controls on upperCanvas
61985    // transparentCorners || ctx.clearRect(-xSizeBy2, -ySizeBy2, xSize, ySize);
61986    ctx[methodName + 'Rect'](-xSizeBy2, -ySizeBy2, xSize, ySize);
61987    if (stroke) {
61988      ctx.strokeRect(-xSizeBy2, -ySizeBy2, xSize, ySize);
61989    }
61990    ctx.restore();
61991  }
61992
61993  controls.renderCircleControl = renderCircleControl;
61994  controls.renderSquareControl = renderSquareControl;
61995
61996})( true ? exports : this
vendor: 12,834 bytes, lines 61996-62337
61996);
61997
61998
61999(function(global) {
62000
62001  'use strict';
62002
62003  var fabric = global.fabric || (global.fabric = { });
62004
62005  function Control(options) {
62006    for (var i in options) {
62007      this[i] = options[i];
62008    }
62009  }
62010
62011  fabric.Control = Control;
62012
62013  fabric.Control.prototype = /** @lends fabric.Control.prototype */ {
62014
62015    /**
62016     * keep track of control visibility.
62017     * mainly for backward compatibility.
62018     * if you do not want to see a control, you can remove it
62019     * from the controlset.
62020     * @type {Boolean}
62021     * @default true
62022     */
62023    visible: true,
62024
62025    /**
62026     * Name of the action that the control will likely execute.
62027     * This is optional. FabricJS uses to identify what the user is doing for some
62028     * extra optimizations. If you are writing a custom control and you want to know
62029     * somewhere else in the code what is going on, you can use this string here.
62030     * you can also provide a custom getActionName if your control run multiple actions
62031     * depending on some external state.
62032     * default to scale since is the most common, used on 4 corners by default
62033     * @type {String}
62034     * @default 'scale'
62035     */
62036    actionName: 'scale',
62037
62038    /**
62039     * Drawing angle of the control.
62040     * NOT used for now, but name marked as needed for internal logic
62041     * example: to reuse the same drawing function for different rotated controls
62042     * @type {Number}
62043     * @default 0
62044     */
62045    angle: 0,
62046
62047    /**
62048     * Relative position of the control. X
62049     * 0,0 is the center of the Object, while -0.5 (left) or 0.5 (right) are the extremities
62050     * of the bounding box.
62051     * @type {Number}
62052     * @default 0
62053     */
62054    x: 0,
62055
62056    /**
62057     * Relative position of the control. Y
62058     * 0,0 is the center of the Object, while -0.5 (top) or 0.5 (bottom) are the extremities
62059     * of the bounding box.
62060     * @type {Number}
62061     * @default 0
62062     */
62063    y: 0,
62064
62065    /**
62066     * Horizontal offset of the control from the defined position. In pixels
62067     * Positive offset moves the control to the right, negative to the left.
62068     * It used when you want to have position of control that does not scale with
62069     * the bounding box. Example: rotation control is placed at x:0, y: 0.5 on
62070     * the boundindbox, with an offset of 30 pixels vertically. Those 30 pixels will
62071     * stay 30 pixels no matter how the object is big. Another example is having 2
62072     * controls in the corner, that stay in the same position when the object scale.
62073     * of the bounding box.
62074     * @type {Number}
62075     * @default 0
62076     */
62077    offsetX: 0,
62078
62079    /**
62080     * Vertical offset of the control from the defined position. In pixels
62081     * Positive offset moves the control to the bottom, negative to the top.
62082     * @type {Number}
62083     * @default 0
62084     */
62085    offsetY: 0,
62086
62087    /**
62088     * Sets the length of the control. If null, defaults to object's cornerSize.
62089     * Expects both sizeX and sizeY to be set when set.
62090     * @type {?Number}
62091     * @default null
62092     */
62093    sizeX: null,
62094
62095    /**
62096     * Sets the height of the control. If null, defaults to object's cornerSize.
62097     * Expects both sizeX and sizeY to be set when set.
62098     * @type {?Number}
62099     * @default null
62100     */
62101    sizeY: null,
62102
62103    /**
62104     * Sets the length of the touch area of the control. If null, defaults to object's touchCornerSize.
62105     * Expects both touchSizeX and touchSizeY to be set when set.
62106     * @type {?Number}
62107     * @default null
62108     */
62109    touchSizeX: null,
62110
62111    /**
62112     * Sets the height of the touch area of the control. If null, defaults to object's touchCornerSize.
62113     * Expects both touchSizeX and touchSizeY to be set when set.
62114     * @type {?Number}
62115     * @default null
62116     */
62117    touchSizeY: null,
62118
62119    /**
62120     * Css cursor style to display when the control is hovered.
62121     * if the method `cursorStyleHandler` is provided, this property is ignored.
62122     * @type {String}
62123     * @default 'crosshair'
62124     */
62125    cursorStyle: 'crosshair',
62126
62127    /**
62128     * If controls has an offsetY or offsetX, draw a line that connects
62129     * the control to the bounding box
62130     * @type {Boolean}
62131     * @default false
62132     */
62133    withConnection: false,
62134
62135    /**
62136     * The control actionHandler, provide one to handle action ( control being moved )
62137     * @param {Event} eventData the native mouse event
62138     * @param {Object} transformData properties of the current transform
62139     * @param {Number} x x position of the cursor
62140     * @param {Number} y y position of the cursor
62141     * @return {Boolean} true if the action/event modified the object
62142     */
62143    actionHandler: function(/* eventData, transformData, x, y */) { },
62144
62145    /**
62146     * The control handler for mouse down, provide one to handle mouse down on control
62147     * @param {Event} eventData the native mouse event
62148     * @param {Object} transformData properties of the current transform
62149     * @param {Number} x x position of the cursor
62150     * @param {Number} y y position of the cursor
62151     * @return {Boolean} true if the action/event modified the object
62152     */
62153    mouseDownHandler: function(/* eventData, transformData, x, y */) { },
62154
62155    /**
62156     * The control mouseUpHandler, provide one to handle an effect on mouse up.
62157     * @param {Event} eventData the native mouse event
62158     * @param {Object} transformData properties of the current transform
62159     * @param {Number} x x position of the cursor
62160     * @param {Number} y y position of the cursor
62161     * @return {Boolean} true if the action/event modified the object
62162     */
62163    mouseUpHandler: function(/* eventData, transformData, x, y */) { },
62164
62165    /**
62166     * Returns control actionHandler
62167     * @param {Event} eventData the native mouse event
62168     * @param {fabric.Object} fabricObject on which the control is displayed
62169     * @param {fabric.Control} control control for which the action handler is being asked
62170     * @return {Function} the action handler
62171     */
62172    getActionHandler: function(/* eventData, fabricObject, control */) {
62173      return this.actionHandler;
62174    },
62175
62176    /**
62177     * Returns control mouseDown handler
62178     * @param {Event} eventData the native mouse event
62179     * @param {fabric.Object} fabricObject on which the control is displayed
62180     * @param {fabric.Control} control control for which the action handler is being asked
62181     * @return {Function} the action handler
62182     */
62183    getMouseDownHandler: function(/* eventData, fabricObject, control */) {
62184      return this.mouseDownHandler;
62185    },
62186
62187    /**
62188     * Returns control mouseUp handler
62189     * @param {Event} eventData the native mouse event
62190     * @param {fabric.Object} fabricObject on which the control is displayed
62191     * @param {fabric.Control} control control for which the action handler is being asked
62192     * @return {Function} the action handler
62193     */
62194    getMouseUpHandler: function(/* eventData, fabricObject, control */) {
62195      return this.mouseUpHandler;
62196    },
62197
62198    /**
62199     * Returns control cursorStyle for css using cursorStyle. If you need a more elaborate
62200     * function you can pass one in the constructor
62201     * the cursorStyle property
62202     * @param {Event} eventData the native mouse event
62203     * @param {fabric.Control} control the current control ( likely this)
62204     * @param {fabric.Object} object on which the control is displayed
62205     * @return {String}
62206     */
62207    cursorStyleHandler: function(eventData, control /* fabricObject */) {
62208      return control.cursorStyle;
62209    },
62210
62211    /**
62212     * Returns the action name. The basic implementation just return the actionName property.
62213     * @param {Event} eventData the native mouse event
62214     * @param {fabric.Control} control the current control ( likely this)
62215     * @param {fabric.Object} object on which the control is displayed
62216     * @return {String}
62217     */
62218    getActionName: function(eventData, control /* fabricObject */) {
62219      return control.actionName;
62220    },
62221
62222    /**
62223     * Returns controls visibility
62224     * @param {fabric.Object} object on which the control is displayed
62225     * @param {String} controlKey key where the control is memorized on the
62226     * @return {Boolean}
62227     */
62228    getVisibility: function(fabricObject, controlKey) {
62229      var objectVisibility = fabricObject._controlsVisibility;
62230      if (objectVisibility && typeof objectVisibility[controlKey] !== 'undefined') {
62231        return objectVisibility[controlKey];
62232      }
62233      return this.visible;
62234    },
62235
62236    /**
62237     * Sets controls visibility
62238     * @param {Boolean} visibility for the object
62239     * @return {Void}
62240     */
62241    setVisibility: function(visibility /* name, fabricObject */) {
62242      this.visible = visibility;
62243    },
62244
62245
62246    positionHandler: function(dim, finalMatrix /*, fabricObject, currentControl */) {
62247      var point = fabric.util.transformPoint({
62248        x: this.x * dim.x + this.offsetX,
62249        y: this.y * dim.y + this.offsetY }, finalMatrix);
62250      return point;
62251    },
62252
62253    /**
62254     * Returns the coords for this control based on object values.
62255     * @param {Number} objectAngle angle from the fabric object holding the control
62256     * @param {Number} objectCornerSize cornerSize from the fabric object holding the control (or touchCornerSize if
62257     *   isTouch is true)
62258     * @param {Number} centerX x coordinate where the control center should be
62259     * @param {Number} centerY y coordinate where the control center should be
62260     * @param {boolean} isTouch true if touch corner, false if normal corner
62261     */
62262    calcCornerCoords: function(objectAngle, objectCornerSize, centerX, centerY, isTouch) {
62263      var cosHalfOffset,
62264          sinHalfOffset,
62265          cosHalfOffsetComp,
62266          sinHalfOffsetComp,
62267          xSize = (isTouch) ? this.touchSizeX : this.sizeX,
62268          ySize = (isTouch) ? this.touchSizeY : this.sizeY;
62269      if (xSize && ySize && xSize !== ySize) {
62270        // handle rectangular corners
62271        var controlTriangleAngle = Math.atan2(ySize, xSize);
62272        var cornerHypotenuse = Math.sqrt(xSize * xSize + ySize * ySize) / 2;
62273        var newTheta = controlTriangleAngle - fabric.util.degreesToRadians(objectAngle);
62274        var newThetaComp = Math.PI / 2 - controlTriangleAngle - fabric.util.degreesToRadians(objectAngle);
62275        cosHalfOffset = cornerHypotenuse * fabric.util.cos(newTheta);
62276        sinHalfOffset = cornerHypotenuse * fabric.util.sin(newTheta);
62277        // use complementary angle for two corners
62278        cosHalfOffsetComp = cornerHypotenuse * fabric.util.cos(newThetaComp);
62279        sinHalfOffsetComp = cornerHypotenuse * fabric.util.sin(newThetaComp);
62280      }
62281      else {
62282        // handle square corners
62283        // use default object corner size unless size is defined
62284        var cornerSize = (xSize && ySize) ? xSize : objectCornerSize;
62285        /* 0.7071067812 stands for sqrt(2)/2 */
62286        cornerHypotenuse = cornerSize * 0.7071067812;
62287        // complementary angles are equal since they're both 45 degrees
62288        var newTheta = fabric.util.degreesToRadians(45 - objectAngle);
62289        cosHalfOffset = cosHalfOffsetComp = cornerHypotenuse * fabric.util.cos(newTheta);
62290        sinHalfOffset = sinHalfOffsetComp = cornerHypotenuse * fabric.util.sin(newTheta);
62291      }
62292
62293      return {
62294        tl: {
62295          x: centerX - sinHalfOffsetComp,
62296          y: centerY - cosHalfOffsetComp,
62297        },
62298        tr: {
62299          x: centerX + cosHalfOffset,
62300          y: centerY - sinHalfOffset,
62301        },
62302        bl: {
62303          x: centerX - cosHalfOffset,
62304          y: centerY + sinHalfOffset,
62305        },
62306        br: {
62307          x: centerX + sinHalfOffsetComp,
62308          y: centerY + cosHalfOffsetComp,
62309        },
62310      };
62311    },
62312
62313    /**
62314    * Render function for the control.
62315    * When this function runs the context is unscaled. unrotate. Just retina scaled.
62316    * all the functions will have to translate to the point left,top before starting Drawing
62317    * if they want to draw a control where the position is detected.
62318    * left and top are the result of the positionHandler function
62319    * @param {RenderingContext2D} ctx the context where the control will be drawn
62320    * @param {Number} left position of the canvas where we are about to render the control.
62321    * @param {Number} top position of the canvas where we are about to render the control.
62322    * @param {Object} styleOverride
62323    * @param {fabric.Object} fabricObject the object where the control is about to be rendered
62324    */
62325    render: function(ctx, left, top, styleOverride, fabricObject) {
62326      styleOverride = styleOverride || {};
62327      switch (styleOverride.cornerStyle || fabricObject.cornerStyle) {
62328        case 'circle':
62329          fabric.controlsUtils.renderCircleControl.call(this, ctx, left, top, styleOverride, fabricObject);
62330          break;
62331        default:
62332          fabric.controlsUtils.renderSquareControl.call(this, ctx, left, top, styleOverride, fabricObject);
62333      }
62334    },
62335  };
62336
62337})( true ? exports : 
62337this
vendor: 28,096 bytes, lines 62337-63217
62337);
62338
62339
62340(function() {
62341
62342  /* _FROM_SVG_START_ */
62343  function getColorStop(el, multiplier) {
62344    var style = el.getAttribute('style'),
62345        offset = el.getAttribute('offset') || 0,
62346        color, colorAlpha, opacity, i;
62347
62348    // convert percents to absolute values
62349    offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);
62350    offset = offset < 0 ? 0 : offset > 1 ? 1 : offset;
62351    if (style) {
62352      var keyValuePairs = style.split(/\s*;\s*/);
62353
62354      if (keyValuePairs[keyValuePairs.length - 1] === '') {
62355        keyValuePairs.pop();
62356      }
62357
62358      for (i = keyValuePairs.length; i--; ) {
62359
62360        var split = keyValuePairs[i].split(/\s*:\s*/),
62361            key = split[0].trim(),
62362            value = split[1].trim();
62363
62364        if (key === 'stop-color') {
62365          color = value;
62366        }
62367        else if (key === 'stop-opacity') {
62368          opacity = value;
62369        }
62370      }
62371    }
62372
62373    if (!color) {
62374      color = el.getAttribute('stop-color') || 'rgb(0,0,0)';
62375    }
62376    if (!opacity) {
62377      opacity = el.getAttribute('stop-opacity');
62378    }
62379
62380    color = new fabric.Color(color);
62381    colorAlpha = color.getAlpha();
62382    opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);
62383    opacity *= colorAlpha * multiplier;
62384
62385    return {
62386      offset: offset,
62387      color: color.toRgb(),
62388      opacity: opacity
62389    };
62390  }
62391
62392  function getLinearCoords(el) {
62393    return {
62394      x1: el.getAttribute('x1') || 0,
62395      y1: el.getAttribute('y1') || 0,
62396      x2: el.getAttribute('x2') || '100%',
62397      y2: el.getAttribute('y2') || 0
62398    };
62399  }
62400
62401  function getRadialCoords(el) {
62402    return {
62403      x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%',
62404      y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%',
62405      r1: 0,
62406      x2: el.getAttribute('cx') || '50%',
62407      y2: el.getAttribute('cy') || '50%',
62408      r2: el.getAttribute('r') || '50%'
62409    };
62410  }
62411  /* _FROM_SVG_END_ */
62412
62413  var clone = fabric.util.object.clone;
62414
62415  /**
62416   * Gradient class
62417   * @class fabric.Gradient
62418   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients}
62419   * @see {@link fabric.Gradient#initialize} for constructor definition
62420   */
62421  fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ {
62422
62423    /**
62424     * Horizontal offset for aligning gradients coming from SVG when outside pathgroups
62425     * @type Number
62426     * @default 0
62427     */
62428    offsetX: 0,
62429
62430    /**
62431     * Vertical offset for aligning gradients coming from SVG when outside pathgroups
62432     * @type Number
62433     * @default 0
62434     */
62435    offsetY: 0,
62436
62437    /**
62438     * A transform matrix to apply to the gradient before painting.
62439     * Imported from svg gradients, is not applied with the current transform in the center.
62440     * Before this transform is applied, the origin point is at the top left corner of the object
62441     * plus the addition of offsetY and offsetX.
62442     * @type Number[]
62443     * @default null
62444     */
62445    gradientTransform: null,
62446
62447    /**
62448     * coordinates units for coords.
62449     * If `pixels`, the number of coords are in the same unit of width / height.
62450     * If set as `percentage` the coords are still a number, but 1 means 100% of width
62451     * for the X and 100% of the height for the y. It can be bigger than 1 and negative.
62452     * allowed values pixels or percentage.
62453     * @type String
62454     * @default 'pixels'
62455     */
62456    gradientUnits: 'pixels',
62457
62458    /**
62459     * Gradient type linear or radial
62460     * @type String
62461     * @default 'pixels'
62462     */
62463    type: 'linear',
62464
62465    /**
62466     * Constructor
62467     * @param {Object} options Options object with type, coords, gradientUnits and colorStops
62468     * @param {Object} [options.type] gradient type linear or radial
62469     * @param {Object} [options.gradientUnits] gradient units
62470     * @param {Object} [options.offsetX] SVG import compatibility
62471     * @param {Object} [options.offsetY] SVG import compatibility
62472     * @param {Object[]} options.colorStops contains the colorstops.
62473     * @param {Object} options.coords contains the coords of the gradient
62474     * @param {Number} [options.coords.x1] X coordiante of the first point for linear or of the focal point for radial
62475     * @param {Number} [options.coords.y1] Y coordiante of the first point for linear or of the focal point for radial
62476     * @param {Number} [options.coords.x2] X coordiante of the second point for linear or of the center point for radial
62477     * @param {Number} [options.coords.y2] Y coordiante of the second point for linear or of the center point for radial
62478     * @param {Number} [options.coords.r1] only for radial gradient, radius of the inner circle
62479     * @param {Number} [options.coords.r2] only for radial gradient, radius of the external circle
62480     * @return {fabric.Gradient} thisArg
62481     */
62482    initialize: function(options) {
62483      options || (options = { });
62484      options.coords || (options.coords = { });
62485
62486      var coords, _this = this;
62487
62488      // sets everything, then coords and colorstops get sets again
62489      Object.keys(options).forEach(function(option) {
62490        _this[option] = options[option];
62491      });
62492
62493      if (this.id) {
62494        this.id += '_' + fabric.Object.__uid++;
62495      }
62496      else {
62497        this.id = fabric.Object.__uid++;
62498      }
62499
62500      coords = {
62501        x1: options.coords.x1 || 0,
62502        y1: options.coords.y1 || 0,
62503        x2: options.coords.x2 || 0,
62504        y2: options.coords.y2 || 0
62505      };
62506
62507      if (this.type === 'radial') {
62508        coords.r1 = options.coords.r1 || 0;
62509        coords.r2 = options.coords.r2 || 0;
62510      }
62511
62512      this.coords = coords;
62513      this.colorStops = options.colorStops.slice();
62514    },
62515
62516    /**
62517     * Adds another colorStop
62518     * @param {Object} colorStop Object with offset and color
62519     * @return {fabric.Gradient} thisArg
62520     */
62521    addColorStop: function(colorStops) {
62522      for (var position in colorStops) {
62523        var color = new fabric.Color(colorStops[position]);
62524        this.colorStops.push({
62525          offset: parseFloat(position),
62526          color: color.toRgb(),
62527          opacity: color.getAlpha()
62528        });
62529      }
62530      return this;
62531    },
62532
62533    /**
62534     * Returns object representation of a gradient
62535     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
62536     * @return {Object}
62537     */
62538    toObject: function(propertiesToInclude) {
62539      var object = {
62540        type: this.type,
62541        coords: this.coords,
62542        colorStops: this.colorStops,
62543        offsetX: this.offsetX,
62544        offsetY: this.offsetY,
62545        gradientUnits: this.gradientUnits,
62546        gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform
62547      };
62548      fabric.util.populateWithProperties(this, object, propertiesToInclude);
62549
62550      return object;
62551    },
62552
62553    /* _TO_SVG_START_ */
62554    /**
62555     * Returns SVG representation of an gradient
62556     * @param {Object} object Object to create a gradient for
62557     * @return {String} SVG representation of an gradient (linear/radial)
62558     */
62559    toSVG: function(object, options) {
62560      var coords = clone(this.coords, true), i, len, options = options || {},
62561          markup, commonAttributes, colorStops = clone(this.colorStops, true),
62562          needsSwap = coords.r1 > coords.r2,
62563          transform = this.gradientTransform ? this.gradientTransform.concat() : fabric.iMatrix.concat(),
62564          offsetX = -this.offsetX, offsetY = -this.offsetY,
62565          withViewport = !!options.additionalTransform,
62566          gradientUnits = this.gradientUnits === 'pixels' ? 'userSpaceOnUse' : 'objectBoundingBox';
62567      // colorStops must be sorted ascending
62568      colorStops.sort(function(a, b) {
62569        return a.offset - b.offset;
62570      });
62571
62572      if (gradientUnits === 'objectBoundingBox') {
62573        offsetX /= object.width;
62574        offsetY /= object.height;
62575      }
62576      else {
62577        offsetX += object.width / 2;
62578        offsetY += object.height / 2;
62579      }
62580      if (object.type === 'path' && this.gradientUnits !== 'percentage') {
62581        offsetX -= object.pathOffset.x;
62582        offsetY -= object.pathOffset.y;
62583      }
62584
62585
62586      transform[4] -= offsetX;
62587      transform[5] -= offsetY;
62588
62589      commonAttributes = 'id="SVGID_' + this.id +
62590                     '" gradientUnits="' + gradientUnits + '"';
62591      commonAttributes += ' gradientTransform="' + (withViewport ?
62592        options.additionalTransform + ' ' : '') + fabric.util.matrixToSVG(transform) + '" ';
62593
62594      if (this.type === 'linear') {
62595        markup = [
62596          '<linearGradient ',
62597          commonAttributes,
62598          ' x1="', coords.x1,
62599          '" y1="', coords.y1,
62600          '" x2="', coords.x2,
62601          '" y2="', coords.y2,
62602          '">\n'
62603        ];
62604      }
62605      else if (this.type === 'radial') {
62606        // svg radial gradient has just 1 radius. the biggest.
62607        markup = [
62608          '<radialGradient ',
62609          commonAttributes,
62610          ' cx="', needsSwap ? coords.x1 : coords.x2,
62611          '" cy="', needsSwap ? coords.y1 : coords.y2,
62612          '" r="', needsSwap ? coords.r1 : coords.r2,
62613          '" fx="', needsSwap ? coords.x2 : coords.x1,
62614          '" fy="', needsSwap ? coords.y2 : coords.y1,
62615          '">\n'
62616        ];
62617      }
62618
62619      if (this.type === 'radial') {
62620        if (needsSwap) {
62621          // svg goes from internal to external radius. if radius are inverted, swap color stops.
62622          colorStops = colorStops.concat();
62623          colorStops.reverse();
62624          for (i = 0, len = colorStops.length; i < len; i++) {
62625            colorStops[i].offset = 1 - colorStops[i].offset;
62626          }
62627        }
62628        var minRadius = Math.min(coords.r1, coords.r2);
62629        if (minRadius > 0) {
62630          // i have to shift all colorStops and add new one in 0.
62631          var maxRadius = Math.max(coords.r1, coords.r2),
62632              percentageShift = minRadius / maxRadius;
62633          for (i = 0, len = colorStops.length; i < len; i++) {
62634            colorStops[i].offset += percentageShift * (1 - colorStops[i].offset);
62635          }
62636        }
62637      }
62638
62639      for (i = 0, len = colorStops.length; i < len; i++) {
62640        var colorStop = colorStops[i];
62641        markup.push(
62642          '<stop ',
62643          'offset="', (colorStop.offset * 100) + '%',
62644          '" style="stop-color:', colorStop.color,
62645          (typeof colorStop.opacity !== 'undefined' ? ';stop-opacity: ' + colorStop.opacity : ';'),
62646          '"/>\n'
62647        );
62648      }
62649
62650      markup.push((this.type === 'linear' ? '</linearGradient>\n' : '</radialGradient>\n'));
62651
62652      return markup.join('');
62653    },
62654    /* _TO_SVG_END_ */
62655
62656    /**
62657     * Returns an instance of CanvasGradient
62658     * @param {CanvasRenderingContext2D} ctx Context to render on
62659     * @return {CanvasGradient}
62660     */
62661    toLive: function(ctx) {
62662      var gradient, coords = fabric.util.object.clone(this.coords), i, len;
62663
62664      if (!this.type) {
62665        return;
62666      }
62667
62668      if (this.type === 'linear') {
62669        gradient = ctx.createLinearGradient(
62670          coords.x1, coords.y1, coords.x2, coords.y2);
62671      }
62672      else if (this.type === 'radial') {
62673        gradient = ctx.createRadialGradient(
62674          coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2);
62675      }
62676
62677      for (i = 0, len = this.colorStops.length; i < len; i++) {
62678        var color = this.colorStops[i].color,
62679            opacity = this.colorStops[i].opacity,
62680            offset = this.colorStops[i].offset;
62681
62682        if (typeof opacity !== 'undefined') {
62683          color = new fabric.Color(color).setAlpha(opacity).toRgba();
62684        }
62685        gradient.addColorStop(offset, color);
62686      }
62687
62688      return gradient;
62689    }
62690  });
62691
62692  fabric.util.object.extend(fabric.Gradient, {
62693
62694    /* _FROM_SVG_START_ */
62695    /**
62696     * Returns {@link fabric.Gradient} instance from an SVG element
62697     * @static
62698     * @memberOf fabric.Gradient
62699     * @param {SVGGradientElement} el SVG gradient element
62700     * @param {fabric.Object} instance
62701     * @param {String} opacityAttr A fill-opacity or stroke-opacity attribute to multiply to each stop's opacity.
62702     * @param {Object} svgOptions an object containing the size of the SVG in order to parse correctly gradients
62703     * that uses gradientUnits as 'userSpaceOnUse' and percentages.
62704     * @param {Object.number} viewBoxWidth width part of the viewBox attribute on svg
62705     * @param {Object.number} viewBoxHeight height part of the viewBox attribute on svg
62706     * @param {Object.number} width width part of the svg tag if viewBox is not specified
62707     * @param {Object.number} height height part of the svg tag if viewBox is not specified
62708     * @return {fabric.Gradient} Gradient instance
62709     * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement
62710     * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement
62711     */
62712    fromElement: function(el, instance, opacityAttr, svgOptions) {
62713      /**
62714       *  @example:
62715       *
62716       *  <linearGradient id="linearGrad1">
62717       *    <stop offset="0%" stop-color="white"/>
62718       *    <stop offset="100%" stop-color="black"/>
62719       *  </linearGradient>
62720       *
62721       *  OR
62722       *
62723       *  <linearGradient id="linearGrad2">
62724       *    <stop offset="0" style="stop-color:rgb(255,255,255)"/>
62725       *    <stop offset="1" style="stop-color:rgb(0,0,0)"/>
62726       *  </linearGradient>
62727       *
62728       *  OR
62729       *
62730       *  <radialGradient id="radialGrad1">
62731       *    <stop offset="0%" stop-color="white" stop-opacity="1" />
62732       *    <stop offset="50%" stop-color="black" stop-opacity="0.5" />
62733       *    <stop offset="100%" stop-color="white" stop-opacity="1" />
62734       *  </radialGradient>
62735       *
62736       *  OR
62737       *
62738       *  <radialGradient id="radialGrad2">
62739       *    <stop offset="0" stop-color="rgb(255,255,255)" />
62740       *    <stop offset="0.5" stop-color="rgb(0,0,0)" />
62741       *    <stop offset="1" stop-color="rgb(255,255,255)" />
62742       *  </radialGradient>
62743       *
62744       */
62745
62746      var multiplier = parseFloat(opacityAttr) / (/%$/.test(opacityAttr) ? 100 : 1);
62747      multiplier = multiplier < 0 ? 0 : multiplier > 1 ? 1 : multiplier;
62748      if (isNaN(multiplier)) {
62749        multiplier = 1;
62750      }
62751
62752      var colorStopEls = el.getElementsByTagName('stop'),
62753          type,
62754          gradientUnits = el.getAttribute('gradientUnits') === 'userSpaceOnUse' ?
62755            'pixels' : 'percentage',
62756          gradientTransform = el.getAttribute('gradientTransform') || '',
62757          colorStops = [],
62758          coords, i, offsetX = 0, offsetY = 0,
62759          transformMatrix;
62760      if (el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT') {
62761        type = 'linear';
62762        coords = getLinearCoords(el);
62763      }
62764      else {
62765        type = 'radial';
62766        coords = getRadialCoords(el);
62767      }
62768
62769      for (i = colorStopEls.length; i--; ) {
62770        colorStops.push(getColorStop(colorStopEls[i], multiplier));
62771      }
62772
62773      transformMatrix = fabric.parseTransformAttribute(gradientTransform);
62774
62775      __convertPercentUnitsToValues(instance, coords, svgOptions, gradientUnits);
62776
62777      if (gradientUnits === 'pixels') {
62778        offsetX = -instance.left;
62779        offsetY = -instance.top;
62780      }
62781
62782      var gradient = new fabric.Gradient({
62783        id: el.getAttribute('id'),
62784        type: type,
62785        coords: coords,
62786        colorStops: colorStops,
62787        gradientUnits: gradientUnits,
62788        gradientTransform: transformMatrix,
62789        offsetX: offsetX,
62790        offsetY: offsetY,
62791      });
62792
62793      return gradient;
62794    }
62795    /* _FROM_SVG_END_ */
62796  });
62797
62798  /**
62799   * @private
62800   */
62801  function __convertPercentUnitsToValues(instance, options, svgOptions, gradientUnits) {
62802    var propValue, finalValue;
62803    Object.keys(options).forEach(function(prop) {
62804      propValue = options[prop];
62805      if (propValue === 'Infinity') {
62806        finalValue = 1;
62807      }
62808      else if (propValue === '-Infinity') {
62809        finalValue = 0;
62810      }
62811      else {
62812        finalValue = parseFloat(options[prop], 10);
62813        if (typeof propValue === 'string' && /^(\d+\.\d+)%|(\d+)%$/.test(propValue)) {
62814          finalValue *= 0.01;
62815          if (gradientUnits === 'pixels') {
62816            // then we need to fix those percentages here in svg parsing
62817            if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
62818              finalValue *= svgOptions.viewBoxWidth || svgOptions.width;
62819            }
62820            if (prop === 'y1' || prop === 'y2') {
62821              finalValue *= svgOptions.viewBoxHeight || svgOptions.height;
62822            }
62823          }
62824        }
62825      }
62826      options[prop] = finalValue;
62827    });
62828  }
62829})();
62830
62831
62832(function() {
62833
62834  'use strict';
62835
62836  var toFixed = fabric.util.toFixed;
62837
62838  /**
62839   * Pattern class
62840   * @class fabric.Pattern
62841   * @see {@link http://fabricjs.com/patterns|Pattern demo}
62842   * @see {@link http://fabricjs.com/dynamic-patterns|DynamicPattern demo}
62843   * @see {@link fabric.Pattern#initialize} for constructor definition
62844   */
62845
62846
62847  fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ {
62848
62849    /**
62850     * Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)
62851     * @type String
62852     * @default
62853     */
62854    repeat: 'repeat',
62855
62856    /**
62857     * Pattern horizontal offset from object's left/top corner
62858     * @type Number
62859     * @default
62860     */
62861    offsetX: 0,
62862
62863    /**
62864     * Pattern vertical offset from object's left/top corner
62865     * @type Number
62866     * @default
62867     */
62868    offsetY: 0,
62869
62870    /**
62871     * crossOrigin value (one of "", "anonymous", "use-credentials")
62872     * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes
62873     * @type String
62874     * @default
62875     */
62876    crossOrigin: '',
62877
62878    /**
62879     * transform matrix to change the pattern, imported from svgs.
62880     * @type Array
62881     * @default
62882     */
62883    patternTransform: null,
62884
62885    /**
62886     * Constructor
62887     * @param {Object} [options] Options object
62888     * @param {Function} [callback] function to invoke after callback init.
62889     * @return {fabric.Pattern} thisArg
62890     */
62891    initialize: function(options, callback) {
62892      options || (options = { });
62893
62894      this.id = fabric.Object.__uid++;
62895      this.setOptions(options);
62896      if (!options.source || (options.source && typeof options.source !== 'string')) {
62897        callback && callback(this);
62898        return;
62899      }
62900      else {
62901        // img src string
62902        var _this = this;
62903        this.source = fabric.util.createImage();
62904        fabric.util.loadImage(options.source, function(img, isError) {
62905          _this.source = img;
62906          callback && callback(_this, isError);
62907        }, null, this.crossOrigin);
62908      }
62909    },
62910
62911    /**
62912     * Returns object representation of a pattern
62913     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
62914     * @return {Object} Object representation of a pattern instance
62915     */
62916    toObject: function(propertiesToInclude) {
62917      var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,
62918          source, object;
62919
62920      // <img> element
62921      if (typeof this.source.src === 'string') {
62922        source = this.source.src;
62923      }
62924      // <canvas> element
62925      else if (typeof this.source === 'object' && this.source.toDataURL) {
62926        source = this.source.toDataURL();
62927      }
62928
62929      object = {
62930        type: 'pattern',
62931        source: source,
62932        repeat: this.repeat,
62933        crossOrigin: this.crossOrigin,
62934        offsetX: toFixed(this.offsetX, NUM_FRACTION_DIGITS),
62935        offsetY: toFixed(this.offsetY, NUM_FRACTION_DIGITS),
62936        patternTransform: this.patternTransform ? this.patternTransform.concat() : null
62937      };
62938      fabric.util.populateWithProperties(this, object, propertiesToInclude);
62939
62940      return object;
62941    },
62942
62943    /* _TO_SVG_START_ */
62944    /**
62945     * Returns SVG representation of a pattern
62946     * @param {fabric.Object} object
62947     * @return {String} SVG representation of a pattern
62948     */
62949    toSVG: function(object) {
62950      var patternSource = typeof this.source === 'function' ? this.source() : this.source,
62951          patternWidth = patternSource.width / object.width,
62952          patternHeight = patternSource.height / object.height,
62953          patternOffsetX = this.offsetX / object.width,
62954          patternOffsetY = this.offsetY / object.height,
62955          patternImgSrc = '';
62956      if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') {
62957        patternHeight = 1;
62958        if (patternOffsetY) {
62959          patternHeight += Math.abs(patternOffsetY);
62960        }
62961      }
62962      if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') {
62963        patternWidth = 1;
62964        if (patternOffsetX) {
62965          patternWidth += Math.abs(patternOffsetX);
62966        }
62967
62968      }
62969      if (patternSource.src) {
62970        patternImgSrc = patternSource.src;
62971      }
62972      else if (patternSource.toDataURL) {
62973        patternImgSrc = patternSource.toDataURL();
62974      }
62975
62976      return '<pattern id="SVGID_' + this.id +
62977                    '" x="' + patternOffsetX +
62978                    '" y="' + patternOffsetY +
62979                    '" width="' + patternWidth +
62980                    '" height="' + patternHeight + '">\n' +
62981               '<image x="0" y="0"' +
62982                      ' width="' + patternSource.width +
62983                      '" height="' + patternSource.height +
62984                      '" xlink:href="' + patternImgSrc +
62985               '"></image>\n' +
62986             '</pattern>\n';
62987    },
62988    /* _TO_SVG_END_ */
62989
62990    setOptions: function(options) {
62991      for (var prop in options) {
62992        this[prop] = options[prop];
62993      }
62994    },
62995
62996    /**
62997     * Returns an instance of CanvasPattern
62998     * @param {CanvasRenderingContext2D} ctx Context to create pattern
62999     * @return {CanvasPattern}
63000     */
63001    toLive: function(ctx) {
63002      var source = this.source;
63003      // if the image failed to load, return, and allow rest to continue loading
63004      if (!source) {
63005        return '';
63006      }
63007
63008      // if an image
63009      if (typeof source.src !== 'undefined') {
63010        if (!source.complete) {
63011          return '';
63012        }
63013        if (source.naturalWidth === 0 || source.naturalHeight === 0) {
63014          return '';
63015        }
63016      }
63017      return ctx.createPattern(source, this.repeat);
63018    }
63019  });
63020})();
63021
63022
63023(function(global) {
63024
63025  'use strict';
63026
63027  var fabric = global.fabric || (global.fabric = { }),
63028      toFixed = fabric.util.toFixed;
63029
63030  if (fabric.Shadow) {
63031    fabric.warn('fabric.Shadow is already defined.');
63032    return;
63033  }
63034
63035  /**
63036   * Shadow class
63037   * @class fabric.Shadow
63038   * @see {@link http://fabricjs.com/shadows|Shadow demo}
63039   * @see {@link fabric.Shadow#initialize} for constructor definition
63040   */
63041  fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ {
63042
63043    /**
63044     * Shadow color
63045     * @type String
63046     * @default
63047     */
63048    color: 'rgb(0,0,0)',
63049
63050    /**
63051     * Shadow blur
63052     * @type Number
63053     */
63054    blur: 0,
63055
63056    /**
63057     * Shadow horizontal offset
63058     * @type Number
63059     * @default
63060     */
63061    offsetX: 0,
63062
63063    /**
63064     * Shadow vertical offset
63065     * @type Number
63066     * @default
63067     */
63068    offsetY: 0,
63069
63070    /**
63071     * Whether the shadow should affect stroke operations
63072     * @type Boolean
63073     * @default
63074     */
63075    affectStroke: false,
63076
63077    /**
63078     * Indicates whether toObject should include default values
63079     * @type Boolean
63080     * @default
63081     */
63082    includeDefaultValues: true,
63083
63084    /**
63085     * When `false`, the shadow will scale with the object.
63086     * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale.
63087     * default to false
63088     * @type Boolean
63089     * @default
63090     */
63091    nonScaling: false,
63092
63093    /**
63094     * Constructor
63095     * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. "rgba(0,0,0,0.2) 2px 2px 10px")
63096     * @return {fabric.Shadow} thisArg
63097     */
63098    initialize: function(options) {
63099
63100      if (typeof options === 'string') {
63101        options = this._parseShadow(options);
63102      }
63103
63104      for (var prop in options) {
63105        this[prop] = options[prop];
63106      }
63107
63108      this.id = fabric.Object.__uid++;
63109    },
63110
63111    /**
63112     * @private
63113     * @param {String} shadow Shadow value to parse
63114     * @return {Object} Shadow object with color, offsetX, offsetY and blur
63115     */
63116    _parseShadow: function(shadow) {
63117      var shadowStr = shadow.trim(),
63118          offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [],
63119          color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)';
63120
63121      return {
63122        color: color.trim(),
63123        offsetX: parseFloat(offsetsAndBlur[1], 10) || 0,
63124        offsetY: parseFloat(offsetsAndBlur[2], 10) || 0,
63125        blur: parseFloat(offsetsAndBlur[3], 10) || 0
63126      };
63127    },
63128
63129    /**
63130     * Returns a string representation of an instance
63131     * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow
63132     * @return {String} Returns CSS3 text-shadow declaration
63133     */
63134    toString: function() {
63135      return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');
63136    },
63137
63138    /* _TO_SVG_START_ */
63139    /**
63140     * Returns SVG representation of a shadow
63141     * @param {fabric.Object} object
63142     * @return {String} SVG representation of a shadow
63143     */
63144    toSVG: function(object) {
63145      var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,
63146          offset = fabric.util.rotateVector(
63147            { x: this.offsetX, y: this.offsetY },
63148            fabric.util.degreesToRadians(-object.angle)),
63149          BLUR_BOX = 20, color = new fabric.Color(this.color);
63150
63151      if (object.width && object.height) {
63152        //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
63153        // we add some extra space to filter box to contain the blur ( 20 )
63154        fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;
63155        fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;
63156      }
63157      if (object.flipX) {
63158        offset.x *= -1;
63159      }
63160      if (object.flipY) {
63161        offset.y *= -1;
63162      }
63163
63164      return (
63165        '<filter id="SVGID_' + this.id + '" y="-' + fBoxY + '%" height="' + (100 + 2 * fBoxY) + '%" ' +
63166          'x="-' + fBoxX + '%" width="' + (100 + 2 * fBoxX) + '%" ' + '>\n' +
63167          '\t<feGaussianBlur in="SourceAlpha" stdDeviation="' +
63168            toFixed(this.blur ? this.blur / 2 : 0, NUM_FRACTION_DIGITS) + '"></feGaussianBlur>\n' +
63169          '\t<feOffset dx="' + toFixed(offset.x, NUM_FRACTION_DIGITS) +
63170          '" dy="' + toFixed(offset.y, NUM_FRACTION_DIGITS) + '" result="oBlur" ></feOffset>\n' +
63171          '\t<feFlood flood-color="' + color.toRgb() + '" flood-opacity="' + color.getAlpha() + '"/>\n' +
63172          '\t<feComposite in2="oBlur" operator="in" />\n' +
63173          '\t<feMerge>\n' +
63174            '\t\t<feMergeNode></feMergeNode>\n' +
63175            '\t\t<feMergeNode in="SourceGraphic"></feMergeNode>\n' +
63176          '\t</feMerge>\n' +
63177        '</filter>\n');
63178    },
63179    /* _TO_SVG_END_ */
63180
63181    /**
63182     * Returns object representation of a shadow
63183     * @return {Object} Object representation of a shadow instance
63184     */
63185    toObject: function() {
63186      if (this.includeDefaultValues) {
63187        return {
63188          color: this.color,
63189          blur: this.blur,
63190          offsetX: this.offsetX,
63191          offsetY: this.offsetY,
63192          affectStroke: this.affectStroke,
63193          nonScaling: this.nonScaling
63194        };
63195      }
63196      var obj = { }, proto = fabric.Shadow.prototype;
63197
63198      ['color', 'blur', 'offsetX', 'offsetY', 'affectStroke', 'nonScaling'].forEach(function(prop) {
63199        if (this[prop] !== proto[prop]) {
63200          obj[prop] = this[prop];
63201        }
63202      }, this);
63203
63204      return obj;
63205    }
63206  });
63207
63208  /**
63209   * Regex matching shadow offsetX, offsetY and blur (ex: "2px 2px 10px rgba(0,0,0,0.2)", "rgb(0,255,0) 2px 2px")
63210   * @static
63211   * @field
63212   * @memberOf fabric.Shadow
63213   */
63214  // eslint-disable-next-line max-len
63215  fabric.Shadow.reOffsetsAndBlur = /(?:\s|^)(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?(\d+(?:\.\d*)?(?:px)?)?(?:\s?|$)(?:$|\s)/;
63216
63217})( true ? exports : 
63217this
vendor: 246,494 bytes, lines 63217-70761
63217);
63218
63219
63220(function () {
63221
63222  'use strict';
63223
63224  if (fabric.StaticCanvas) {
63225    fabric.warn('fabric.StaticCanvas is already defined.');
63226    return;
63227  }
63228
63229  // aliases for faster resolution
63230  var extend = fabric.util.object.extend,
63231      getElementOffset = fabric.util.getElementOffset,
63232      removeFromArray = fabric.util.removeFromArray,
63233      toFixed = fabric.util.toFixed,
63234      transformPoint = fabric.util.transformPoint,
63235      invertTransform = fabric.util.invertTransform,
63236      getNodeCanvas = fabric.util.getNodeCanvas,
63237      createCanvasElement = fabric.util.createCanvasElement,
63238
63239      CANVAS_INIT_ERROR = new Error('Could not initialize `canvas` element');
63240
63241  /**
63242   * Static canvas class
63243   * @class fabric.StaticCanvas
63244   * @mixes fabric.Collection
63245   * @mixes fabric.Observable
63246   * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}
63247   * @see {@link fabric.StaticCanvas#initialize} for constructor definition
63248   * @fires before:render
63249   * @fires after:render
63250   * @fires canvas:cleared
63251   * @fires object:added
63252   * @fires object:removed
63253   */
63254  fabric.StaticCanvas = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.StaticCanvas.prototype */ {
63255
63256    /**
63257     * Constructor
63258     * @param {HTMLElement | String} el &lt;canvas> element to initialize instance on
63259     * @param {Object} [options] Options object
63260     * @return {Object} thisArg
63261     */
63262    initialize: function(el, options) {
63263      options || (options = { });
63264      this.renderAndResetBound = this.renderAndReset.bind(this);
63265      this.requestRenderAllBound = this.requestRenderAll.bind(this);
63266      this._initStatic(el, options);
63267    },
63268
63269    /**
63270     * Background color of canvas instance.
63271     * Should be set via {@link fabric.StaticCanvas#setBackgroundColor}.
63272     * @type {(String|fabric.Pattern)}
63273     * @default
63274     */
63275    backgroundColor: '',
63276
63277    /**
63278     * Background image of canvas instance.
63279     * since 2.4.0 image caching is active, please when putting an image as background, add to the
63280     * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom
63281     * vale. As an alternative you can disable image objectCaching
63282     * @type fabric.Image
63283     * @default
63284     */
63285    backgroundImage: null,
63286
63287    /**
63288     * Overlay color of canvas instance.
63289     * Should be set via {@link fabric.StaticCanvas#setOverlayColor}
63290     * @since 1.3.9
63291     * @type {(String|fabric.Pattern)}
63292     * @default
63293     */
63294    overlayColor: '',
63295
63296    /**
63297     * Overlay image of canvas instance.
63298     * since 2.4.0 image caching is active, please when putting an image as overlay, add to the
63299     * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom
63300     * vale. As an alternative you can disable image objectCaching
63301     * @type fabric.Image
63302     * @default
63303     */
63304    overlayImage: null,
63305
63306    /**
63307     * Indicates whether toObject/toDatalessObject should include default values
63308     * if set to false, takes precedence over the object value.
63309     * @type Boolean
63310     * @default
63311     */
63312    includeDefaultValues: true,
63313
63314    /**
63315     * Indicates whether objects' state should be saved
63316     * @type Boolean
63317     * @default
63318     */
63319    stateful: false,
63320
63321    /**
63322     * Indicates whether {@link fabric.Collection.add}, {@link fabric.Collection.insertAt} and {@link fabric.Collection.remove},
63323     * {@link fabric.StaticCanvas.moveTo}, {@link fabric.StaticCanvas.clear} and many more, should also re-render canvas.
63324     * Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once
63325     * since the renders are quequed and executed one per frame.
63326     * Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() )
63327     * Left default to true to do not break documentation and old app, fiddles.
63328     * @type Boolean
63329     * @default
63330     */
63331    renderOnAddRemove: true,
63332
63333    /**
63334     * Indicates whether object controls (borders/controls) are rendered above overlay image
63335     * @type Boolean
63336     * @default
63337     */
63338    controlsAboveOverlay: false,
63339
63340    /**
63341     * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas
63342     * @type Boolean
63343     * @default
63344     */
63345    allowTouchScrolling: false,
63346
63347    /**
63348     * Indicates whether this canvas will use image smoothing, this is on by default in browsers
63349     * @type Boolean
63350     * @default
63351     */
63352    imageSmoothingEnabled: true,
63353
63354    /**
63355     * The transformation (in the format of Canvas transform) which focuses the viewport
63356     * @type Array
63357     * @default
63358     */
63359    viewportTransform: fabric.iMatrix.concat(),
63360
63361    /**
63362     * if set to false background image is not affected by viewport transform
63363     * @since 1.6.3
63364     * @type Boolean
63365     * @default
63366     */
63367    backgroundVpt: true,
63368
63369    /**
63370     * if set to false overlya image is not affected by viewport transform
63371     * @since 1.6.3
63372     * @type Boolean
63373     * @default
63374     */
63375    overlayVpt: true,
63376
63377    /**
63378     * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens
63379     * @type Boolean
63380     * @default
63381     */
63382    enableRetinaScaling: true,
63383
63384    /**
63385     * Describe canvas element extension over design
63386     * properties are tl,tr,bl,br.
63387     * if canvas is not zoomed/panned those points are the four corner of canvas
63388     * if canvas is viewportTransformed you those points indicate the extension
63389     * of canvas element in plain untrasformed coordinates
63390     * The coordinates get updated with @method calcViewportBoundaries.
63391     * @memberOf fabric.StaticCanvas.prototype
63392     */
63393    vptCoords: { },
63394
63395    /**
63396     * Based on vptCoords and object.aCoords, skip rendering of objects that
63397     * are not included in current viewport.
63398     * May greatly help in applications with crowded canvas and use of zoom/pan
63399     * If One of the corner of the bounding box of the object is on the canvas
63400     * the objects get rendered.
63401     * @memberOf fabric.StaticCanvas.prototype
63402     * @type Boolean
63403     * @default
63404     */
63405    skipOffscreen: true,
63406
63407    /**
63408     * a fabricObject that, without stroke define a clipping area with their shape. filled in black
63409     * the clipPath object gets used when the canvas has rendered, and the context is placed in the
63410     * top left corner of the canvas.
63411     * clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true
63412     * @type fabric.Object
63413     */
63414    clipPath: undefined,
63415
63416    /**
63417     * @private
63418     * @param {HTMLElement | String} el &lt;canvas> element to initialize instance on
63419     * @param {Object} [options] Options object
63420     */
63421    _initStatic: function(el, options) {
63422      var cb = this.requestRenderAllBound;
63423      this._objects = [];
63424      this._createLowerCanvas(el);
63425      this._initOptions(options);
63426      // only initialize retina scaling once
63427      if (!this.interactive) {
63428        this._initRetinaScaling();
63429      }
63430
63431      if (options.overlayImage) {
63432        this.setOverlayImage(options.overlayImage, cb);
63433      }
63434      if (options.backgroundImage) {
63435        this.setBackgroundImage(options.backgroundImage, cb);
63436      }
63437      if (options.backgroundColor) {
63438        this.setBackgroundColor(options.backgroundColor, cb);
63439      }
63440      if (options.overlayColor) {
63441        this.setOverlayColor(options.overlayColor, cb);
63442      }
63443      this.calcOffset();
63444    },
63445
63446    /**
63447     * @private
63448     */
63449    _isRetinaScaling: function() {
63450      return (fabric.devicePixelRatio !== 1 && this.enableRetinaScaling);
63451    },
63452
63453    /**
63454     * @private
63455     * @return {Number} retinaScaling if applied, otherwise 1;
63456     */
63457    getRetinaScaling: function() {
63458      return this._isRetinaScaling() ? fabric.devicePixelRatio : 1;
63459    },
63460
63461    /**
63462     * @private
63463     */
63464    _initRetinaScaling: function() {
63465      if (!this._isRetinaScaling()) {
63466        return;
63467      }
63468      var scaleRatio = fabric.devicePixelRatio;
63469      this.__initRetinaScaling(scaleRatio, this.lowerCanvasEl, this.contextContainer);
63470      if (this.upperCanvasEl) {
63471        this.__initRetinaScaling(scaleRatio, this.upperCanvasEl, this.contextTop);
63472      }
63473    },
63474
63475    __initRetinaScaling: function(scaleRatio, canvas, context) {
63476      canvas.setAttribute('width', this.width * scaleRatio);
63477      canvas.setAttribute('height', this.height * scaleRatio);
63478      context.scale(scaleRatio, scaleRatio);
63479    },
63480
63481
63482    /**
63483     * Calculates canvas element offset relative to the document
63484     * This method is also attached as "resize" event handler of window
63485     * @return {fabric.Canvas} instance
63486     * @chainable
63487     */
63488    calcOffset: function () {
63489      this._offset = getElementOffset(this.lowerCanvasEl);
63490      return this;
63491    },
63492
63493    /**
63494     * Sets {@link fabric.StaticCanvas#overlayImage|overlay image} for this canvas
63495     * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set overlay to
63496     * @param {Function} callback callback to invoke when image is loaded and set as an overlay
63497     * @param {Object} [options] Optional options to set for the {@link fabric.Image|overlay image}.
63498     * @return {fabric.Canvas} thisArg
63499     * @chainable
63500     * @see {@link http://jsfiddle.net/fabricjs/MnzHT/|jsFiddle demo}
63501     * @example <caption>Normal overlayImage with left/top = 0</caption>
63502     * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {
63503     *   // Needed to position overlayImage at 0/0
63504     *   originX: 'left',
63505     *   originY: 'top'
63506     * });
63507     * @example <caption>overlayImage with different properties</caption>
63508     * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {
63509     *   opacity: 0.5,
63510     *   angle: 45,
63511     *   left: 400,
63512     *   top: 400,
63513     *   originX: 'left',
63514     *   originY: 'top'
63515     * });
63516     * @example <caption>Stretched overlayImage #1 - width/height correspond to canvas width/height</caption>
63517     * fabric.Image.fromURL('http://fabricjs.com/assets/jail_cell_bars.png', function(img, isError) {
63518     *    img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});
63519     *    canvas.setOverlayImage(img, canvas.renderAll.bind(canvas));
63520     * });
63521     * @example <caption>Stretched overlayImage #2 - width/height correspond to canvas width/height</caption>
63522     * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {
63523     *   width: canvas.width,
63524     *   height: canvas.height,
63525     *   // Needed to position overlayImage at 0/0
63526     *   originX: 'left',
63527     *   originY: 'top'
63528     * });
63529     * @example <caption>overlayImage loaded from cross-origin</caption>
63530     * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {
63531     *   opacity: 0.5,
63532     *   angle: 45,
63533     *   left: 400,
63534     *   top: 400,
63535     *   originX: 'left',
63536     *   originY: 'top',
63537     *   crossOrigin: 'anonymous'
63538     * });
63539     */
63540    setOverlayImage: function (image, callback, options) {
63541      return this.__setBgOverlayImage('overlayImage', image, callback, options);
63542    },
63543
63544    /**
63545     * Sets {@link fabric.StaticCanvas#backgroundImage|background image} for this canvas
63546     * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background to
63547     * @param {Function} callback Callback to invoke when image is loaded and set as background
63548     * @param {Object} [options] Optional options to set for the {@link fabric.Image|background image}.
63549     * @return {fabric.Canvas} thisArg
63550     * @chainable
63551     * @see {@link http://jsfiddle.net/djnr8o7a/28/|jsFiddle demo}
63552     * @example <caption>Normal backgroundImage with left/top = 0</caption>
63553     * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {
63554     *   // Needed to position backgroundImage at 0/0
63555     *   originX: 'left',
63556     *   originY: 'top'
63557     * });
63558     * @example <caption>backgroundImage with different properties</caption>
63559     * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {
63560     *   opacity: 0.5,
63561     *   angle: 45,
63562     *   left: 400,
63563     *   top: 400,
63564     *   originX: 'left',
63565     *   originY: 'top'
63566     * });
63567     * @example <caption>Stretched backgroundImage #1 - width/height correspond to canvas width/height</caption>
63568     * fabric.Image.fromURL('http://fabricjs.com/assets/honey_im_subtle.png', function(img, isError) {
63569     *    img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});
63570     *    canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));
63571     * });
63572     * @example <caption>Stretched backgroundImage #2 - width/height correspond to canvas width/height</caption>
63573     * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {
63574     *   width: canvas.width,
63575     *   height: canvas.height,
63576     *   // Needed to position backgroundImage at 0/0
63577     *   originX: 'left',
63578     *   originY: 'top'
63579     * });
63580     * @example <caption>backgroundImage loaded from cross-origin</caption>
63581     * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {
63582     *   opacity: 0.5,
63583     *   angle: 45,
63584     *   left: 400,
63585     *   top: 400,
63586     *   originX: 'left',
63587     *   originY: 'top',
63588     *   crossOrigin: 'anonymous'
63589     * });
63590     */
63591    // TODO: fix stretched examples
63592    setBackgroundImage: function (image, callback, options) {
63593      return this.__setBgOverlayImage('backgroundImage', image, callback, options);
63594    },
63595
63596    /**
63597     * Sets {@link fabric.StaticCanvas#overlayColor|foreground color} for this canvas
63598     * @param {(String|fabric.Pattern)} overlayColor Color or pattern to set foreground color to
63599     * @param {Function} callback Callback to invoke when foreground color is set
63600     * @return {fabric.Canvas} thisArg
63601     * @chainable
63602     * @see {@link http://jsfiddle.net/fabricjs/pB55h/|jsFiddle demo}
63603     * @example <caption>Normal overlayColor - color value</caption>
63604     * canvas.setOverlayColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));
63605     * @example <caption>fabric.Pattern used as overlayColor</caption>
63606     * canvas.setOverlayColor({
63607     *   source: 'http://fabricjs.com/assets/escheresque_ste.png'
63608     * }, canvas.renderAll.bind(canvas));
63609     * @example <caption>fabric.Pattern used as overlayColor with repeat and offset</caption>
63610     * canvas.setOverlayColor({
63611     *   source: 'http://fabricjs.com/assets/escheresque_ste.png',
63612     *   repeat: 'repeat',
63613     *   offsetX: 200,
63614     *   offsetY: 100
63615     * }, canvas.renderAll.bind(canvas));
63616     */
63617    setOverlayColor: function(overlayColor, callback) {
63618      return this.__setBgOverlayColor('overlayColor', overlayColor, callback);
63619    },
63620
63621    /**
63622     * Sets {@link fabric.StaticCanvas#backgroundColor|background color} for this canvas
63623     * @param {(String|fabric.Pattern)} backgroundColor Color or pattern to set background color to
63624     * @param {Function} callback Callback to invoke when background color is set
63625     * @return {fabric.Canvas} thisArg
63626     * @chainable
63627     * @see {@link http://jsfiddle.net/fabricjs/hXzvk/|jsFiddle demo}
63628     * @example <caption>Normal backgroundColor - color value</caption>
63629     * canvas.setBackgroundColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));
63630     * @example <caption>fabric.Pattern used as backgroundColor</caption>
63631     * canvas.setBackgroundColor({
63632     *   source: 'http://fabricjs.com/assets/escheresque_ste.png'
63633     * }, canvas.renderAll.bind(canvas));
63634     * @example <caption>fabric.Pattern used as backgroundColor with repeat and offset</caption>
63635     * canvas.setBackgroundColor({
63636     *   source: 'http://fabricjs.com/assets/escheresque_ste.png',
63637     *   repeat: 'repeat',
63638     *   offsetX: 200,
63639     *   offsetY: 100
63640     * }, canvas.renderAll.bind(canvas));
63641     */
63642    setBackgroundColor: function(backgroundColor, callback) {
63643      return this.__setBgOverlayColor('backgroundColor', backgroundColor, callback);
63644    },
63645
63646    /**
63647     * @private
63648     * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage}
63649     * or {@link fabric.StaticCanvas#overlayImage|overlayImage})
63650     * @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to
63651     * @param {Function} callback Callback to invoke when image is loaded and set as background or overlay. The first argument is the created image, the second argument is a flag indicating whether an error occurred or not.
63652     * @param {Object} [options] Optional options to set for the {@link fabric.Image|image}.
63653     */
63654    __setBgOverlayImage: function(property, image, callback, options) {
63655      if (typeof image === 'string') {
63656        fabric.util.loadImage(image, function(img, isError) {
63657          if (img) {
63658            var instance = new fabric.Image(img, options);
63659            this[property] = instance;
63660            instance.canvas = this;
63661          }
63662          callback && callback(img, isError);
63663        }, this, options && options.crossOrigin);
63664      }
63665      else {
63666        options && image.setOptions(options);
63667        this[property] = image;
63668        image && (image.canvas = this);
63669        callback && callback(image, false);
63670      }
63671
63672      return this;
63673    },
63674
63675    /**
63676     * @private
63677     * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor}
63678     * or {@link fabric.StaticCanvas#overlayColor|overlayColor})
63679     * @param {(Object|String|null)} color Object with pattern information, color value or null
63680     * @param {Function} [callback] Callback is invoked when color is set
63681     */
63682    __setBgOverlayColor: function(property, color, callback) {
63683      this[property] = color;
63684      this._initGradient(color, property);
63685      this._initPattern(color, property, callback);
63686      return this;
63687    },
63688
63689    /**
63690     * @private
63691     */
63692    _createCanvasElement: function() {
63693      var element = createCanvasElement();
63694      if (!element) {
63695        throw CANVAS_INIT_ERROR;
63696      }
63697      if (!element.style) {
63698        element.style = { };
63699      }
63700      if (typeof element.getContext === 'undefined') {
63701        throw CANVAS_INIT_ERROR;
63702      }
63703      return element;
63704    },
63705
63706    /**
63707     * @private
63708     * @param {Object} [options] Options object
63709     */
63710    _initOptions: function (options) {
63711      var lowerCanvasEl = this.lowerCanvasEl;
63712      this._setOptions(options);
63713
63714      this.width = this.width || parseInt(lowerCanvasEl.width, 10) || 0;
63715      this.height = this.height || parseInt(lowerCanvasEl.height, 10) || 0;
63716
63717      if (!this.lowerCanvasEl.style) {
63718        return;
63719      }
63720
63721      lowerCanvasEl.width = this.width;
63722      lowerCanvasEl.height = this.height;
63723
63724      lowerCanvasEl.style.width = this.width + 'px';
63725      lowerCanvasEl.style.height = this.height + 'px';
63726
63727      this.viewportTransform = this.viewportTransform.slice();
63728    },
63729
63730    /**
63731     * Creates a bottom canvas
63732     * @private
63733     * @param {HTMLElement} [canvasEl]
63734     */
63735    _createLowerCanvas: function (canvasEl) {
63736      // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node
63737      if (canvasEl && canvasEl.getContext) {
63738        this.lowerCanvasEl = canvasEl;
63739      }
63740      else {
63741        this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement();
63742      }
63743
63744      fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas');
63745      this._originalCanvasStyle = this.lowerCanvasEl.style;
63746      if (this.interactive) {
63747        this._applyCanvasStyle(this.lowerCanvasEl);
63748      }
63749
63750      this.contextContainer = this.lowerCanvasEl.getContext('2d');
63751    },
63752
63753    /**
63754     * Returns canvas width (in px)
63755     * @return {Number}
63756     */
63757    getWidth: function () {
63758      return this.width;
63759    },
63760
63761    /**
63762     * Returns canvas height (in px)
63763     * @return {Number}
63764     */
63765    getHeight: function () {
63766      return this.height;
63767    },
63768
63769    /**
63770     * Sets width of this canvas instance
63771     * @param {Number|String} value                         Value to set width to
63772     * @param {Object}        [options]                     Options object
63773     * @param {Boolean}       [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions
63774     * @param {Boolean}       [options.cssOnly=false]       Set the given dimensions only as css dimensions
63775     * @return {fabric.Canvas} instance
63776     * @chainable true
63777     */
63778    setWidth: function (value, options) {
63779      return this.setDimensions({ width: value }, options);
63780    },
63781
63782    /**
63783     * Sets height of this canvas instance
63784     * @param {Number|String} value                         Value to set height to
63785     * @param {Object}        [options]                     Options object
63786     * @param {Boolean}       [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions
63787     * @param {Boolean}       [options.cssOnly=false]       Set the given dimensions only as css dimensions
63788     * @return {fabric.Canvas} instance
63789     * @chainable true
63790     */
63791    setHeight: function (value, options) {
63792      return this.setDimensions({ height: value }, options);
63793    },
63794
63795    /**
63796     * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)
63797     * @param {Object}        dimensions                    Object with width/height properties
63798     * @param {Number|String} [dimensions.width]            Width of canvas element
63799     * @param {Number|String} [dimensions.height]           Height of canvas element
63800     * @param {Object}        [options]                     Options object
63801     * @param {Boolean}       [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions
63802     * @param {Boolean}       [options.cssOnly=false]       Set the given dimensions only as css dimensions
63803     * @return {fabric.Canvas} thisArg
63804     * @chainable
63805     */
63806    setDimensions: function (dimensions, options) {
63807      var cssValue;
63808
63809      options = options || {};
63810
63811      for (var prop in dimensions) {
63812        cssValue = dimensions[prop];
63813
63814        if (!options.cssOnly) {
63815          this._setBackstoreDimension(prop, dimensions[prop]);
63816          cssValue += 'px';
63817          this.hasLostContext = true;
63818        }
63819
63820        if (!options.backstoreOnly) {
63821          this._setCssDimension(prop, cssValue);
63822        }
63823      }
63824      if (this._isCurrentlyDrawing) {
63825        this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles();
63826      }
63827      this._initRetinaScaling();
63828      this.calcOffset();
63829
63830      if (!options.cssOnly) {
63831        this.requestRenderAll();
63832      }
63833
63834      return this;
63835    },
63836
63837    /**
63838     * Helper for setting width/height
63839     * @private
63840     * @param {String} prop property (width|height)
63841     * @param {Number} value value to set property to
63842     * @return {fabric.Canvas} instance
63843     * @chainable true
63844     */
63845    _setBackstoreDimension: function (prop, value) {
63846      this.lowerCanvasEl[prop] = value;
63847
63848      if (this.upperCanvasEl) {
63849        this.upperCanvasEl[prop] = value;
63850      }
63851
63852      if (this.cacheCanvasEl) {
63853        this.cacheCanvasEl[prop] = value;
63854      }
63855
63856      this[prop] = value;
63857
63858      return this;
63859    },
63860
63861    /**
63862     * Helper for setting css width/height
63863     * @private
63864     * @param {String} prop property (width|height)
63865     * @param {String} value value to set property to
63866     * @return {fabric.Canvas} instance
63867     * @chainable true
63868     */
63869    _setCssDimension: function (prop, value) {
63870      this.lowerCanvasEl.style[prop] = value;
63871
63872      if (this.upperCanvasEl) {
63873        this.upperCanvasEl.style[prop] = value;
63874      }
63875
63876      if (this.wrapperEl) {
63877        this.wrapperEl.style[prop] = value;
63878      }
63879
63880      return this;
63881    },
63882
63883    /**
63884     * Returns canvas zoom level
63885     * @return {Number}
63886     */
63887    getZoom: function () {
63888      return this.viewportTransform[0];
63889    },
63890
63891    /**
63892     * Sets viewport transform of this canvas instance
63893     * @param {Array} vpt the transform in the form of context.transform
63894     * @return {fabric.Canvas} instance
63895     * @chainable true
63896     */
63897    setViewportTransform: function (vpt) {
63898      var activeObject = this._activeObject,
63899          backgroundObject = this.backgroundImage,
63900          overlayObject = this.overlayImage,
63901          object, i, len;
63902      this.viewportTransform = vpt;
63903      for (i = 0, len = this._objects.length; i < len; i++) {
63904        object = this._objects[i];
63905        object.group || object.setCoords(true);
63906      }
63907      if (activeObject) {
63908        activeObject.setCoords();
63909      }
63910      if (backgroundObject) {
63911        backgroundObject.setCoords(true);
63912      }
63913      if (overlayObject) {
63914        overlayObject.setCoords(true);
63915      }
63916      this.calcViewportBoundaries();
63917      this.renderOnAddRemove && this.requestRenderAll();
63918      return this;
63919    },
63920
63921    /**
63922     * Sets zoom level of this canvas instance, the zoom centered around point
63923     * meaning that following zoom to point with the same point will have the visual
63924     * effect of the zoom originating from that point. The point won't move.
63925     * It has nothing to do with canvas center or visual center of the viewport.
63926     * @param {fabric.Point} point to zoom with respect to
63927     * @param {Number} value to set zoom to, less than 1 zooms out
63928     * @return {fabric.Canvas} instance
63929     * @chainable true
63930     */
63931    zoomToPoint: function (point, value) {
63932      // TODO: just change the scale, preserve other transformations
63933      var before = point, vpt = this.viewportTransform.slice(0);
63934      point = transformPoint(point, invertTransform(this.viewportTransform));
63935      vpt[0] = value;
63936      vpt[3] = value;
63937      var after = transformPoint(point, vpt);
63938      vpt[4] += before.x - after.x;
63939      vpt[5] += before.y - after.y;
63940      return this.setViewportTransform(vpt);
63941    },
63942
63943    /**
63944     * Sets zoom level of this canvas instance
63945     * @param {Number} value to set zoom to, less than 1 zooms out
63946     * @return {fabric.Canvas} instance
63947     * @chainable true
63948     */
63949    setZoom: function (value) {
63950      this.zoomToPoint(new fabric.Point(0, 0), value);
63951      return this;
63952    },
63953
63954    /**
63955     * Pan viewport so as to place point at top left corner of canvas
63956     * @param {fabric.Point} point to move to
63957     * @return {fabric.Canvas} instance
63958     * @chainable true
63959     */
63960    absolutePan: function (point) {
63961      var vpt = this.viewportTransform.slice(0);
63962      vpt[4] = -point.x;
63963      vpt[5] = -point.y;
63964      return this.setViewportTransform(vpt);
63965    },
63966
63967    /**
63968     * Pans viewpoint relatively
63969     * @param {fabric.Point} point (position vector) to move by
63970     * @return {fabric.Canvas} instance
63971     * @chainable true
63972     */
63973    relativePan: function (point) {
63974      return this.absolutePan(new fabric.Point(
63975        -point.x - this.viewportTransform[4],
63976        -point.y - this.viewportTransform[5]
63977      ));
63978    },
63979
63980    /**
63981     * Returns &lt;canvas> element corresponding to this instance
63982     * @return {HTMLCanvasElement}
63983     */
63984    getElement: function () {
63985      return this.lowerCanvasEl;
63986    },
63987
63988    /**
63989     * @private
63990     * @param {fabric.Object} obj Object that was added
63991     */
63992    _onObjectAdded: function(obj) {
63993      this.stateful && obj.setupState();
63994      obj._set('canvas', this);
63995      obj.setCoords();
63996      this.fire('object:added', { target: obj });
63997      obj.fire('added');
63998    },
63999
64000    /**
64001     * @private
64002     * @param {fabric.Object} obj Object that was removed
64003     */
64004    _onObjectRemoved: function(obj) {
64005      this.fire('object:removed', { target: obj });
64006      obj.fire('removed');
64007      delete obj.canvas;
64008    },
64009
64010    /**
64011     * Clears specified context of canvas element
64012     * @param {CanvasRenderingContext2D} ctx Context to clear
64013     * @return {fabric.Canvas} thisArg
64014     * @chainable
64015     */
64016    clearContext: function(ctx) {
64017      ctx.clearRect(0, 0, this.width, this.height);
64018      return this;
64019    },
64020
64021    /**
64022     * Returns context of canvas where objects are drawn
64023     * @return {CanvasRenderingContext2D}
64024     */
64025    getContext: function () {
64026      return this.contextContainer;
64027    },
64028
64029    /**
64030     * Clears all contexts (background, main, top) of an instance
64031     * @return {fabric.Canvas} thisArg
64032     * @chainable
64033     */
64034    clear: function () {
64035      this.remove.apply(this, this.getObjects());
64036      this.backgroundImage = null;
64037      this.overlayImage = null;
64038      this.backgroundColor = '';
64039      this.overlayColor = '';
64040      if (this._hasITextHandlers) {
64041        this.off('mouse:up', this._mouseUpITextHandler);
64042        this._iTextInstances = null;
64043        this._hasITextHandlers = false;
64044      }
64045      this.clearContext(this.contextContainer);
64046      this.fire('canvas:cleared');
64047      this.renderOnAddRemove && this.requestRenderAll();
64048      return this;
64049    },
64050
64051    /**
64052     * Renders the canvas
64053     * @return {fabric.Canvas} instance
64054     * @chainable
64055     */
64056    renderAll: function () {
64057      var canvasToDrawOn = this.contextContainer;
64058      this.renderCanvas(canvasToDrawOn, this._objects);
64059      return this;
64060    },
64061
64062    /**
64063     * Function created to be instance bound at initialization
64064     * used in requestAnimationFrame rendering
64065     * Let the fabricJS call it. If you call it manually you could have more
64066     * animationFrame stacking on to of each other
64067     * for an imperative rendering, use canvas.renderAll
64068     * @private
64069     * @return {fabric.Canvas} instance
64070     * @chainable
64071     */
64072    renderAndReset: function() {
64073      this.isRendering = 0;
64074      this.renderAll();
64075    },
64076
64077    /**
64078     * Append a renderAll request to next animation frame.
64079     * unless one is already in progress, in that case nothing is done
64080     * a boolean flag will avoid appending more.
64081     * @return {fabric.Canvas} instance
64082     * @chainable
64083     */
64084    requestRenderAll: function () {
64085      if (!this.isRendering) {
64086        this.isRendering = fabric.util.requestAnimFrame(this.renderAndResetBound);
64087      }
64088      return this;
64089    },
64090
64091    /**
64092     * Calculate the position of the 4 corner of canvas with current viewportTransform.
64093     * helps to determinate when an object is in the current rendering viewport using
64094     * object absolute coordinates ( aCoords )
64095     * @return {Object} points.tl
64096     * @chainable
64097     */
64098    calcViewportBoundaries: function() {
64099      var points = { }, width = this.width, height = this.height,
64100          iVpt = invertTransform(this.viewportTransform);
64101      points.tl = transformPoint({ x: 0, y: 0 }, iVpt);
64102      points.br = transformPoint({ x: width, y: height }, iVpt);
64103      points.tr = new fabric.Point(points.br.x, points.tl.y);
64104      points.bl = new fabric.Point(points.tl.x, points.br.y);
64105      this.vptCoords = points;
64106      return points;
64107    },
64108
64109    cancelRequestedRender: function() {
64110      if (this.isRendering) {
64111        fabric.util.cancelAnimFrame(this.isRendering);
64112        this.isRendering = 0;
64113      }
64114    },
64115
64116    /**
64117     * Renders background, objects, overlay and controls.
64118     * @param {CanvasRenderingContext2D} ctx
64119     * @param {Array} objects to render
64120     * @return {fabric.Canvas} instance
64121     * @chainable
64122     */
64123    renderCanvas: function(ctx, objects) {
64124      var v = this.viewportTransform, path = this.clipPath;
64125      this.cancelRequestedRender();
64126      this.calcViewportBoundaries();
64127      this.clearContext(ctx);
64128      fabric.util.setImageSmoothing(ctx, this.imageSmoothingEnabled);
64129      this.fire('before:render', { ctx: ctx, });
64130      this._renderBackground(ctx);
64131
64132      ctx.save();
64133      //apply viewport transform once for all rendering process
64134      ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
64135      this._renderObjects(ctx, objects);
64136      ctx.restore();
64137      if (!this.controlsAboveOverlay && this.interactive) {
64138        this.drawControls(ctx);
64139      }
64140      if (path) {
64141        path.canvas = this;
64142        // needed to setup a couple of variables
64143        path.shouldCache();
64144        path._transformDone = true;
64145        path.renderCache({ forClipping: true });
64146        this.drawClipPathOnCanvas(ctx);
64147      }
64148      this._renderOverlay(ctx);
64149      if (this.controlsAboveOverlay && this.interactive) {
64150        this.drawControls(ctx);
64151      }
64152      this.fire('after:render', { ctx: ctx, });
64153    },
64154
64155    /**
64156     * Paint the cached clipPath on the lowerCanvasEl
64157     * @param {CanvasRenderingContext2D} ctx Context to render on
64158     */
64159    drawClipPathOnCanvas: function(ctx) {
64160      var v = this.viewportTransform, path = this.clipPath;
64161      ctx.save();
64162      ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
64163      // DEBUG: uncomment this line, comment the following
64164      // ctx.globalAlpha = 0.4;
64165      ctx.globalCompositeOperation = 'destination-in';
64166      path.transform(ctx);
64167      ctx.scale(1 / path.zoomX, 1 / path.zoomY);
64168      ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY);
64169      ctx.restore();
64170    },
64171
64172    /**
64173     * @private
64174     * @param {CanvasRenderingContext2D} ctx Context to render on
64175     * @param {Array} objects to render
64176     */
64177    _renderObjects: function(ctx, objects) {
64178      var i, len;
64179      for (i = 0, len = objects.length; i < len; ++i) {
64180        objects[i] && objects[i].render(ctx);
64181      }
64182    },
64183
64184    /**
64185     * @private
64186     * @param {CanvasRenderingContext2D} ctx Context to render on
64187     * @param {string} property 'background' or 'overlay'
64188     */
64189    _renderBackgroundOrOverlay: function(ctx, property) {
64190      var fill = this[property + 'Color'], object = this[property + 'Image'],
64191          v = this.viewportTransform, needsVpt = this[property + 'Vpt'];
64192      if (!fill && !object) {
64193        return;
64194      }
64195      if (fill) {
64196        ctx.save();
64197        ctx.beginPath();
64198        ctx.moveTo(0, 0);
64199        ctx.lineTo(this.width, 0);
64200        ctx.lineTo(this.width, this.height);
64201        ctx.lineTo(0, this.height);
64202        ctx.closePath();
64203        ctx.fillStyle = fill.toLive
64204          ? fill.toLive(ctx, this)
64205          : fill;
64206        if (needsVpt) {
64207          ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
64208        }
64209        ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0);
64210        var m = fill.gradientTransform || fill.patternTransform;
64211        m && ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
64212        ctx.fill();
64213        ctx.restore();
64214      }
64215      if (object) {
64216        ctx.save();
64217        if (needsVpt) {
64218          ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
64219        }
64220        object.render(ctx);
64221        ctx.restore();
64222      }
64223    },
64224
64225    /**
64226     * @private
64227     * @param {CanvasRenderingContext2D} ctx Context to render on
64228     */
64229    _renderBackground: function(ctx) {
64230      this._renderBackgroundOrOverlay(ctx, 'background');
64231    },
64232
64233    /**
64234     * @private
64235     * @param {CanvasRenderingContext2D} ctx Context to render on
64236     */
64237    _renderOverlay: function(ctx) {
64238      this._renderBackgroundOrOverlay(ctx, 'overlay');
64239    },
64240
64241    /**
64242     * Returns coordinates of a center of canvas.
64243     * Returned value is an object with top and left properties
64244     * @return {Object} object with "top" and "left" number values
64245     */
64246    getCenter: function () {
64247      return {
64248        top: this.height / 2,
64249        left: this.width / 2
64250      };
64251    },
64252
64253    /**
64254     * Centers object horizontally in the canvas
64255     * @param {fabric.Object} object Object to center horizontally
64256     * @return {fabric.Canvas} thisArg
64257     */
64258    centerObjectH: function (object) {
64259      return this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y));
64260    },
64261
64262    /**
64263     * Centers object vertically in the canvas
64264     * @param {fabric.Object} object Object to center vertically
64265     * @return {fabric.Canvas} thisArg
64266     * @chainable
64267     */
64268    centerObjectV: function (object) {
64269      return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top));
64270    },
64271
64272    /**
64273     * Centers object vertically and horizontally in the canvas
64274     * @param {fabric.Object} object Object to center vertically and horizontally
64275     * @return {fabric.Canvas} thisArg
64276     * @chainable
64277     */
64278    centerObject: function(object) {
64279      var center = this.getCenter();
64280
64281      return this._centerObject(object, new fabric.Point(center.left, center.top));
64282    },
64283
64284    /**
64285     * Centers object vertically and horizontally in the viewport
64286     * @param {fabric.Object} object Object to center vertically and horizontally
64287     * @return {fabric.Canvas} thisArg
64288     * @chainable
64289     */
64290    viewportCenterObject: function(object) {
64291      var vpCenter = this.getVpCenter();
64292
64293      return this._centerObject(object, vpCenter);
64294    },
64295
64296    /**
64297     * Centers object horizontally in the viewport, object.top is unchanged
64298     * @param {fabric.Object} object Object to center vertically and horizontally
64299     * @return {fabric.Canvas} thisArg
64300     * @chainable
64301     */
64302    viewportCenterObjectH: function(object) {
64303      var vpCenter = this.getVpCenter();
64304      this._centerObject(object, new fabric.Point(vpCenter.x, object.getCenterPoint().y));
64305      return this;
64306    },
64307
64308    /**
64309     * Centers object Vertically in the viewport, object.top is unchanged
64310     * @param {fabric.Object} object Object to center vertically and horizontally
64311     * @return {fabric.Canvas} thisArg
64312     * @chainable
64313     */
64314    viewportCenterObjectV: function(object) {
64315      var vpCenter = this.getVpCenter();
64316
64317      return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, vpCenter.y));
64318    },
64319
64320    /**
64321     * Calculate the point in canvas that correspond to the center of actual viewport.
64322     * @return {fabric.Point} vpCenter, viewport center
64323     * @chainable
64324     */
64325    getVpCenter: function() {
64326      var center = this.getCenter(),
64327          iVpt = invertTransform(this.viewportTransform);
64328      return transformPoint({ x: center.left, y: center.top }, iVpt);
64329    },
64330
64331    /**
64332     * @private
64333     * @param {fabric.Object} object Object to center
64334     * @param {fabric.Point} center Center point
64335     * @return {fabric.Canvas} thisArg
64336     * @chainable
64337     */
64338    _centerObject: function(object, center) {
64339      object.setPositionByOrigin(center, 'center', 'center');
64340      object.setCoords();
64341      this.renderOnAddRemove && this.requestRenderAll();
64342      return this;
64343    },
64344
64345    /**
64346     * Returns dataless JSON representation of canvas
64347     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
64348     * @return {String} json string
64349     */
64350    toDatalessJSON: function (propertiesToInclude) {
64351      return this.toDatalessObject(propertiesToInclude);
64352    },
64353
64354    /**
64355     * Returns object representation of canvas
64356     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
64357     * @return {Object} object representation of an instance
64358     */
64359    toObject: function (propertiesToInclude) {
64360      return this._toObjectMethod('toObject', propertiesToInclude);
64361    },
64362
64363    /**
64364     * Returns dataless object representation of canvas
64365     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
64366     * @return {Object} object representation of an instance
64367     */
64368    toDatalessObject: function (propertiesToInclude) {
64369      return this._toObjectMethod('toDatalessObject', propertiesToInclude);
64370    },
64371
64372    /**
64373     * @private
64374     */
64375    _toObjectMethod: function (methodName, propertiesToInclude) {
64376
64377      var clipPath = this.clipPath, data = {
64378        version: fabric.version,
64379        objects: this._toObjects(methodName, propertiesToInclude),
64380      };
64381      if (clipPath && !clipPath.excludeFromExport) {
64382        data.clipPath = this._toObject(this.clipPath, methodName, propertiesToInclude);
64383      }
64384      extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude));
64385
64386      fabric.util.populateWithProperties(this, data, propertiesToInclude);
64387
64388      return data;
64389    },
64390
64391    /**
64392     * @private
64393     */
64394    _toObjects: function(methodName, propertiesToInclude) {
64395      return this._objects.filter(function(object) {
64396        return !object.excludeFromExport;
64397      }).map(function(instance) {
64398        return this._toObject(instance, methodName, propertiesToInclude);
64399      }, this);
64400    },
64401
64402    /**
64403     * @private
64404     */
64405    _toObject: function(instance, methodName, propertiesToInclude) {
64406      var originalValue;
64407
64408      if (!this.includeDefaultValues) {
64409        originalValue = instance.includeDefaultValues;
64410        instance.includeDefaultValues = false;
64411      }
64412
64413      var object = instance[methodName](propertiesToInclude);
64414      if (!this.includeDefaultValues) {
64415        instance.includeDefaultValues = originalValue;
64416      }
64417      return object;
64418    },
64419
64420    /**
64421     * @private
64422     */
64423    __serializeBgOverlay: function(methodName, propertiesToInclude) {
64424      var data = {}, bgImage = this.backgroundImage, overlayImage = this.overlayImage,
64425          bgColor = this.backgroundColor, overlayColor = this.overlayColor;
64426
64427      if (bgColor && bgColor.toObject) {
64428        if (!bgColor.excludeFromExport) {
64429          data.background = bgColor.toObject(propertiesToInclude);
64430        }
64431      }
64432      else if (bgColor) {
64433        data.background = bgColor;
64434      }
64435
64436      if (overlayColor && overlayColor.toObject) {
64437        if (!overlayColor.excludeFromExport) {
64438          data.overlay = overlayColor.toObject(propertiesToInclude);
64439        }
64440      }
64441      else if (overlayColor) {
64442        data.overlay = overlayColor;
64443      }
64444
64445      if (bgImage && !bgImage.excludeFromExport) {
64446        data.backgroundImage = this._toObject(bgImage, methodName, propertiesToInclude);
64447      }
64448      if (overlayImage && !overlayImage.excludeFromExport) {
64449        data.overlayImage = this._toObject(overlayImage, methodName, propertiesToInclude);
64450      }
64451
64452      return data;
64453    },
64454
64455    /* _TO_SVG_START_ */
64456    /**
64457     * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,
64458     * a zoomed canvas will then produce zoomed SVG output.
64459     * @type Boolean
64460     * @default
64461     */
64462    svgViewportTransformation: true,
64463
64464    /**
64465     * Returns SVG representation of canvas
64466     * @function
64467     * @param {Object} [options] Options object for SVG output
64468     * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included
64469     * @param {Object} [options.viewBox] SVG viewbox object
64470     * @param {Number} [options.viewBox.x] x-coordinate of viewbox
64471     * @param {Number} [options.viewBox.y] y-coordinate of viewbox
64472     * @param {Number} [options.viewBox.width] Width of viewbox
64473     * @param {Number} [options.viewBox.height] Height of viewbox
64474     * @param {String} [options.encoding=UTF-8] Encoding of SVG output
64475     * @param {String} [options.width] desired width of svg with or without units
64476     * @param {String} [options.height] desired height of svg with or without units
64477     * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.
64478     * @return {String} SVG string
64479     * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}
64480     * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}
64481     * @example <caption>Normal SVG output</caption>
64482     * var svg = canvas.toSVG();
64483     * @example <caption>SVG output without preamble (without &lt;?xml ../>)</caption>
64484     * var svg = canvas.toSVG({suppressPreamble: true});
64485     * @example <caption>SVG output with viewBox attribute</caption>
64486     * var svg = canvas.toSVG({
64487     *   viewBox: {
64488     *     x: 100,
64489     *     y: 100,
64490     *     width: 200,
64491     *     height: 300
64492     *   }
64493     * });
64494     * @example <caption>SVG output with different encoding (default: UTF-8)</caption>
64495     * var svg = canvas.toSVG({encoding: 'ISO-8859-1'});
64496     * @example <caption>Modify SVG output with reviver function</caption>
64497     * var svg = canvas.toSVG(null, function(svg) {
64498     *   return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');
64499     * });
64500     */
64501    toSVG: function(options, reviver) {
64502      options || (options = { });
64503      options.reviver = reviver;
64504      var markup = [];
64505
64506      this._setSVGPreamble(markup, options);
64507      this._setSVGHeader(markup, options);
64508      if (this.clipPath) {
64509        markup.push('<g clip-path="url(#' + this.clipPath.clipPathId + ')" >\n');
64510      }
64511      this._setSVGBgOverlayColor(markup, 'background');
64512      this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);
64513      this._setSVGObjects(markup, reviver);
64514      if (this.clipPath) {
64515        markup.push('</g>\n');
64516      }
64517      this._setSVGBgOverlayColor(markup, 'overlay');
64518      this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);
64519
64520      markup.push('</svg>');
64521
64522      return markup.join('');
64523    },
64524
64525    /**
64526     * @private
64527     */
64528    _setSVGPreamble: function(markup, options) {
64529      if (options.suppressPreamble) {
64530        return;
64531      }
64532      markup.push(
64533        '<?xml version="1.0" encoding="', (options.encoding || 'UTF-8'), '" standalone="no" ?>\n',
64534        '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ',
64535        '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n'
64536      );
64537    },
64538
64539    /**
64540     * @private
64541     */
64542    _setSVGHeader: function(markup, options) {
64543      var width = options.width || this.width,
64544          height = options.height || this.height,
64545          vpt, viewBox = 'viewBox="0 0 ' + this.width + ' ' + this.height + '" ',
64546          NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;
64547
64548      if (options.viewBox) {
64549        viewBox = 'viewBox="' +
64550                options.viewBox.x + ' ' +
64551                options.viewBox.y + ' ' +
64552                options.viewBox.width + ' ' +
64553                options.viewBox.height + '" ';
64554      }
64555      else {
64556        if (this.svgViewportTransformation) {
64557          vpt = this.viewportTransform;
64558          viewBox = 'viewBox="' +
64559                  toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + ' ' +
64560                  toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + ' ' +
64561                  toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + ' ' +
64562                  toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '" ';
64563        }
64564      }
64565
64566      markup.push(
64567        '<svg ',
64568        'xmlns="http://www.w3.org/2000/svg" ',
64569        'xmlns:xlink="http://www.w3.org/1999/xlink" ',
64570        'version="1.1" ',
64571        'width="', width, '" ',
64572        'height="', height, '" ',
64573        viewBox,
64574        'xml:space="preserve">\n',
64575        '<desc>Created with Fabric.js ', fabric.version, '</desc>\n',
64576        '<defs>\n',
64577        this.createSVGFontFacesMarkup(),
64578        this.createSVGRefElementsMarkup(),
64579        this.createSVGClipPathMarkup(options),
64580        '</defs>\n'
64581      );
64582    },
64583
64584    createSVGClipPathMarkup: function(options) {
64585      var clipPath = this.clipPath;
64586      if (clipPath) {
64587        clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;
64588        return  '<clipPath id="' + clipPath.clipPathId + '" >\n' +
64589          this.clipPath.toClipPathSVG(options.reviver) +
64590          '</clipPath>\n';
64591      }
64592      return '';
64593    },
64594
64595    /**
64596     * Creates markup containing SVG referenced elements like patterns, gradients etc.
64597     * @return {String}
64598     */
64599    createSVGRefElementsMarkup: function() {
64600      var _this = this,
64601          markup = ['background', 'overlay'].map(function(prop) {
64602            var fill = _this[prop + 'Color'];
64603            if (fill && fill.toLive) {
64604              var shouldTransform = _this[prop + 'Vpt'], vpt = _this.viewportTransform,
64605                  object = {
64606                    width: _this.width / (shouldTransform ? vpt[0] : 1),
64607                    height: _this.height / (shouldTransform ? vpt[3] : 1)
64608                  };
64609              return fill.toSVG(
64610                object,
64611                { additionalTransform: shouldTransform ? fabric.util.matrixToSVG(vpt) : '' }
64612              );
64613            }
64614          });
64615      return markup.join('');
64616    },
64617
64618    /**
64619     * Creates markup containing SVG font faces,
64620     * font URLs for font faces must be collected by developers
64621     * and are not extracted from the DOM by fabricjs
64622     * @param {Array} objects Array of fabric objects
64623     * @return {String}
64624     */
64625    createSVGFontFacesMarkup: function() {
64626      var markup = '', fontList = { }, obj, fontFamily,
64627          style, row, rowIndex, _char, charIndex, i, len,
64628          fontPaths = fabric.fontPaths, objects = [];
64629
64630      this._objects.forEach(function add(object) {
64631        objects.push(object);
64632        if (object._objects) {
64633          object._objects.forEach(add);
64634        }
64635      });
64636
64637      for (i = 0, len = objects.length; i < len; i++) {
64638        obj = objects[i];
64639        fontFamily = obj.fontFamily;
64640        if (obj.type.indexOf('text') === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) {
64641          continue;
64642        }
64643        fontList[fontFamily] = true;
64644        if (!obj.styles) {
64645          continue;
64646        }
64647        style = obj.styles;
64648        for (rowIndex in style) {
64649          row = style[rowIndex];
64650          for (charIndex in row) {
64651            _char = row[charIndex];
64652            fontFamily = _char.fontFamily;
64653            if (!fontList[fontFamily] && fontPaths[fontFamily]) {
64654              fontList[fontFamily] = true;
64655            }
64656          }
64657        }
64658      }
64659
64660      for (var j in fontList) {
64661        markup += [
64662          '\t\t@font-face {\n',
64663          '\t\t\tfont-family: \'', j, '\';\n',
64664          '\t\t\tsrc: url(\'', fontPaths[j], '\');\n',
64665          '\t\t}\n'
64666        ].join('');
64667      }
64668
64669      if (markup) {
64670        markup = [
64671          '\t<style type="text/css">',
64672          '<![CDATA[\n',
64673          markup,
64674          ']]>',
64675          '</style>\n'
64676        ].join('');
64677      }
64678
64679      return markup;
64680    },
64681
64682    /**
64683     * @private
64684     */
64685    _setSVGObjects: function(markup, reviver) {
64686      var instance, i, len, objects = this._objects;
64687      for (i = 0, len = objects.length; i < len; i++) {
64688        instance = objects[i];
64689        if (instance.excludeFromExport) {
64690          continue;
64691        }
64692        this._setSVGObject(markup, instance, reviver);
64693      }
64694    },
64695
64696    /**
64697     * @private
64698     */
64699    _setSVGObject: function(markup, instance, reviver) {
64700      markup.push(instance.toSVG(reviver));
64701    },
64702
64703    /**
64704     * @private
64705     */
64706    _setSVGBgOverlayImage: function(markup, property, reviver) {
64707      if (this[property] && !this[property].excludeFromExport && this[property].toSVG) {
64708        markup.push(this[property].toSVG(reviver));
64709      }
64710    },
64711
64712    /**
64713     * @private
64714     */
64715    _setSVGBgOverlayColor: function(markup, property) {
64716      var filler = this[property + 'Color'], vpt = this.viewportTransform, finalWidth = this.width,
64717          finalHeight = this.height;
64718      if (!filler) {
64719        return;
64720      }
64721      if (filler.toLive) {
64722        var repeat = filler.repeat, iVpt = fabric.util.invertTransform(vpt), shouldInvert = this[property + 'Vpt'],
64723            additionalTransform = shouldInvert ? fabric.util.matrixToSVG(iVpt) : '';
64724        markup.push(
64725          '<rect transform="' + additionalTransform + ' translate(', finalWidth / 2, ',', finalHeight / 2, ')"',
64726          ' x="', filler.offsetX - finalWidth / 2,
64727          '" y="', filler.offsetY - finalHeight / 2, '" ',
64728          'width="',
64729          (repeat === 'repeat-y' || repeat === 'no-repeat'
64730            ? filler.source.width
64731            : finalWidth ),
64732          '" height="',
64733          (repeat === 'repeat-x' || repeat === 'no-repeat'
64734            ? filler.source.height
64735            : finalHeight),
64736          '" fill="url(#SVGID_' + filler.id + ')"',
64737          '></rect>\n'
64738        );
64739      }
64740      else {
64741        markup.push(
64742          '<rect x="0" y="0" width="100%" height="100%" ',
64743          'fill="', filler, '"',
64744          '></rect>\n'
64745        );
64746      }
64747    },
64748    /* _TO_SVG_END_ */
64749
64750    /**
64751     * Moves an object or the objects of a multiple selection
64752     * to the bottom of the stack of drawn objects
64753     * @param {fabric.Object} object Object to send to back
64754     * @return {fabric.Canvas} thisArg
64755     * @chainable
64756     */
64757    sendToBack: function (object) {
64758      if (!object) {
64759        return this;
64760      }
64761      var activeSelection = this._activeObject,
64762          i, obj, objs;
64763      if (object === activeSelection && object.type === 'activeSelection') {
64764        objs = activeSelection._objects;
64765        for (i = objs.length; i--;) {
64766          obj = objs[i];
64767          removeFromArray(this._objects, obj);
64768          this._objects.unshift(obj);
64769        }
64770      }
64771      else {
64772        removeFromArray(this._objects, object);
64773        this._objects.unshift(object);
64774      }
64775      this.renderOnAddRemove && this.requestRenderAll();
64776      return this;
64777    },
64778
64779    /**
64780     * Moves an object or the objects of a multiple selection
64781     * to the top of the stack of drawn objects
64782     * @param {fabric.Object} object Object to send
64783     * @return {fabric.Canvas} thisArg
64784     * @chainable
64785     */
64786    bringToFront: function (object) {
64787      if (!object) {
64788        return this;
64789      }
64790      var activeSelection = this._activeObject,
64791          i, obj, objs;
64792      if (object === activeSelection && object.type === 'activeSelection') {
64793        objs = activeSelection._objects;
64794        for (i = 0; i < objs.length; i++) {
64795          obj = objs[i];
64796          removeFromArray(this._objects, obj);
64797          this._objects.push(obj);
64798        }
64799      }
64800      else {
64801        removeFromArray(this._objects, object);
64802        this._objects.push(object);
64803      }
64804      this.renderOnAddRemove && this.requestRenderAll();
64805      return this;
64806    },
64807
64808    /**
64809     * Moves an object or a selection down in stack of drawn objects
64810     * An optional parameter, intersecting allows to move the object in behind
64811     * the first intersecting object. Where intersection is calculated with
64812     * bounding box. If no intersection is found, there will not be change in the
64813     * stack.
64814     * @param {fabric.Object} object Object to send
64815     * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object
64816     * @return {fabric.Canvas} thisArg
64817     * @chainable
64818     */
64819    sendBackwards: function (object, intersecting) {
64820      if (!object) {
64821        return this;
64822      }
64823      var activeSelection = this._activeObject,
64824          i, obj, idx, newIdx, objs, objsMoved = 0;
64825
64826      if (object === activeSelection && object.type === 'activeSelection') {
64827        objs = activeSelection._objects;
64828        for (i = 0; i < objs.length; i++) {
64829          obj = objs[i];
64830          idx = this._objects.indexOf(obj);
64831          if (idx > 0 + objsMoved) {
64832            newIdx = idx - 1;
64833            removeFromArray(this._objects, obj);
64834            this._objects.splice(newIdx, 0, obj);
64835          }
64836          objsMoved++;
64837        }
64838      }
64839      else {
64840        idx = this._objects.indexOf(object);
64841        if (idx !== 0) {
64842          // if object is not on the bottom of stack
64843          newIdx = this._findNewLowerIndex(object, idx, intersecting);
64844          removeFromArray(this._objects, object);
64845          this._objects.splice(newIdx, 0, object);
64846        }
64847      }
64848      this.renderOnAddRemove && this.requestRenderAll();
64849      return this;
64850    },
64851
64852    /**
64853     * @private
64854     */
64855    _findNewLowerIndex: function(object, idx, intersecting) {
64856      var newIdx, i;
64857
64858      if (intersecting) {
64859        newIdx = idx;
64860
64861        // traverse down the stack looking for the nearest intersecting object
64862        for (i = idx - 1; i >= 0; --i) {
64863
64864          var isIntersecting = object.intersectsWithObject(this._objects[i]) ||
64865                               object.isContainedWithinObject(this._objects[i]) ||
64866                               this._objects[i].isContainedWithinObject(object);
64867
64868          if (isIntersecting) {
64869            newIdx = i;
64870            break;
64871          }
64872        }
64873      }
64874      else {
64875        newIdx = idx - 1;
64876      }
64877
64878      return newIdx;
64879    },
64880
64881    /**
64882     * Moves an object or a selection up in stack of drawn objects
64883     * An optional parameter, intersecting allows to move the object in front
64884     * of the first intersecting object. Where intersection is calculated with
64885     * bounding box. If no intersection is found, there will not be change in the
64886     * stack.
64887     * @param {fabric.Object} object Object to send
64888     * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object
64889     * @return {fabric.Canvas} thisArg
64890     * @chainable
64891     */
64892    bringForward: function (object, intersecting) {
64893      if (!object) {
64894        return this;
64895      }
64896      var activeSelection = this._activeObject,
64897          i, obj, idx, newIdx, objs, objsMoved = 0;
64898
64899      if (object === activeSelection && object.type === 'activeSelection') {
64900        objs = activeSelection._objects;
64901        for (i = objs.length; i--;) {
64902          obj = objs[i];
64903          idx = this._objects.indexOf(obj);
64904          if (idx < this._objects.length - 1 - objsMoved) {
64905            newIdx = idx + 1;
64906            removeFromArray(this._objects, obj);
64907            this._objects.splice(newIdx, 0, obj);
64908          }
64909          objsMoved++;
64910        }
64911      }
64912      else {
64913        idx = this._objects.indexOf(object);
64914        if (idx !== this._objects.length - 1) {
64915          // if object is not on top of stack (last item in an array)
64916          newIdx = this._findNewUpperIndex(object, idx, intersecting);
64917          removeFromArray(this._objects, object);
64918          this._objects.splice(newIdx, 0, object);
64919        }
64920      }
64921      this.renderOnAddRemove && this.requestRenderAll();
64922      return this;
64923    },
64924
64925    /**
64926     * @private
64927     */
64928    _findNewUpperIndex: function(object, idx, intersecting) {
64929      var newIdx, i, len;
64930
64931      if (intersecting) {
64932        newIdx = idx;
64933
64934        // traverse up the stack looking for the nearest intersecting object
64935        for (i = idx + 1, len = this._objects.length; i < len; ++i) {
64936
64937          var isIntersecting = object.intersectsWithObject(this._objects[i]) ||
64938                               object.isContainedWithinObject(this._objects[i]) ||
64939                               this._objects[i].isContainedWithinObject(object);
64940
64941          if (isIntersecting) {
64942            newIdx = i;
64943            break;
64944          }
64945        }
64946      }
64947      else {
64948        newIdx = idx + 1;
64949      }
64950
64951      return newIdx;
64952    },
64953
64954    /**
64955     * Moves an object to specified level in stack of drawn objects
64956     * @param {fabric.Object} object Object to send
64957     * @param {Number} index Position to move to
64958     * @return {fabric.Canvas} thisArg
64959     * @chainable
64960     */
64961    moveTo: function (object, index) {
64962      removeFromArray(this._objects, object);
64963      this._objects.splice(index, 0, object);
64964      return this.renderOnAddRemove && this.requestRenderAll();
64965    },
64966
64967    /**
64968     * Clears a canvas element and dispose objects
64969     * @return {fabric.Canvas} thisArg
64970     * @chainable
64971     */
64972    dispose: function () {
64973      // cancel eventually ongoing renders
64974      if (this.isRendering) {
64975        fabric.util.cancelAnimFrame(this.isRendering);
64976        this.isRendering = 0;
64977      }
64978      this.forEachObject(function(object) {
64979        object.dispose && object.dispose();
64980      });
64981      this._objects = [];
64982      if (this.backgroundImage && this.backgroundImage.dispose) {
64983        this.backgroundImage.dispose();
64984      }
64985      this.backgroundImage = null;
64986      if (this.overlayImage && this.overlayImage.dispose) {
64987        this.overlayImage.dispose();
64988      }
64989      this.overlayImage = null;
64990      this._iTextInstances = null;
64991      this.contextContainer = null;
64992      // restore canvas style
64993      this.lowerCanvasEl.classList.remove('lower-canvas');
64994      this.lowerCanvasEl.style = this._originalCanvasStyle;
64995      delete this._originalCanvasStyle;
64996      // restore canvas size to original size in case retina scaling was applied
64997      this.lowerCanvasEl.setAttribute('width', this.width);
64998      this.lowerCanvasEl.setAttribute('height', this.height);
64999      fabric.util.cleanUpJsdomNode(this.lowerCanvasEl);
65000      this.lowerCanvasEl = undefined;
65001      return this;
65002    },
65003
65004    /**
65005     * Returns a string representation of an instance
65006     * @return {String} string representation of an instance
65007     */
65008    toString: function () {
65009      return '#<fabric.Canvas (' + this.complexity() + '): ' +
65010               '{ objects: ' + this._objects.length + ' }>';
65011    }
65012  });
65013
65014  extend(fabric.StaticCanvas.prototype, fabric.Observable);
65015  extend(fabric.StaticCanvas.prototype, fabric.Collection);
65016  extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter);
65017
65018  extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ {
65019
65020    /**
65021     * @static
65022     * @type String
65023     * @default
65024     */
65025    EMPTY_JSON: '{"objects": [], "background": "white"}',
65026
65027    /**
65028     * Provides a way to check support of some of the canvas methods
65029     * (either those of HTMLCanvasElement itself, or rendering context)
65030     *
65031     * @param {String} methodName Method to check support for;
65032     *                            Could be one of "setLineDash"
65033     * @return {Boolean | null} `true` if method is supported (or at least exists),
65034     *                          `null` if canvas element or context can not be initialized
65035     */
65036    supports: function (methodName) {
65037      var el = createCanvasElement();
65038
65039      if (!el || !el.getContext) {
65040        return null;
65041      }
65042
65043      var ctx = el.getContext('2d');
65044      if (!ctx) {
65045        return null;
65046      }
65047
65048      switch (methodName) {
65049
65050        case 'setLineDash':
65051          return typeof ctx.setLineDash !== 'undefined';
65052
65053        default:
65054          return null;
65055      }
65056    }
65057  });
65058
65059  /**
65060   * Returns Object representation of canvas
65061   * this alias is provided because if you call JSON.stringify on an instance,
65062   * the toJSON object will be invoked if it exists.
65063   * Having a toJSON method means you can do JSON.stringify(myCanvas)
65064   * @function
65065   * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
65066   * @return {Object} JSON compatible object
65067   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}
65068   * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}
65069   * @example <caption>JSON without additional properties</caption>
65070   * var json = canvas.toJSON();
65071   * @example <caption>JSON with additional properties included</caption>
65072   * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']);
65073   * @example <caption>JSON without default values</caption>
65074   * canvas.includeDefaultValues = false;
65075   * var json = canvas.toJSON();
65076   */
65077  fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;
65078
65079  if (fabric.isLikelyNode) {
65080    fabric.StaticCanvas.prototype.createPNGStream = function() {
65081      var impl = getNodeCanvas(this.lowerCanvasEl);
65082      return impl && impl.createPNGStream();
65083    };
65084    fabric.StaticCanvas.prototype.createJPEGStream = function(opts) {
65085      var impl = getNodeCanvas(this.lowerCanvasEl);
65086      return impl && impl.createJPEGStream(opts);
65087    };
65088  }
65089})();
65090
65091
65092/**
65093 * BaseBrush class
65094 * @class fabric.BaseBrush
65095 * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}
65096 */
65097fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ {
65098
65099  /**
65100   * Color of a brush
65101   * @type String
65102   * @default
65103   */
65104  color: 'rgb(0, 0, 0)',
65105
65106  /**
65107   * Width of a brush, has to be a Number, no string literals
65108   * @type Number
65109   * @default
65110   */
65111  width: 1,
65112
65113  /**
65114   * Shadow object representing shadow of this shape.
65115   * <b>Backwards incompatibility note:</b> This property replaces "shadowColor" (String), "shadowOffsetX" (Number),
65116   * "shadowOffsetY" (Number) and "shadowBlur" (Number) since v1.2.12
65117   * @type fabric.Shadow
65118   * @default
65119   */
65120  shadow: null,
65121
65122  /**
65123   * Line endings style of a brush (one of "butt", "round", "square")
65124   * @type String
65125   * @default
65126   */
65127  strokeLineCap: 'round',
65128
65129  /**
65130   * Corner style of a brush (one of "bevel", "round", "miter")
65131   * @type String
65132   * @default
65133   */
65134  strokeLineJoin: 'round',
65135
65136  /**
65137   * Maximum miter length (used for strokeLineJoin = "miter") of a brush's
65138   * @type Number
65139   * @default
65140   */
65141  strokeMiterLimit:         10,
65142
65143  /**
65144   * Stroke Dash Array.
65145   * @type Array
65146   * @default
65147   */
65148  strokeDashArray: null,
65149
65150  /**
65151   * When `true`, the free drawing is limited to the whiteboard size. Default to false.
65152   * @type Boolean
65153   * @default false
65154  */
65155
65156  limitedToCanvasSize: false,
65157
65158
65159  /**
65160   * Sets brush styles
65161   * @private
65162   */
65163  _setBrushStyles: function() {
65164    var ctx = this.canvas.contextTop;
65165    ctx.strokeStyle = this.color;
65166    ctx.lineWidth = this.width;
65167    ctx.lineCap = this.strokeLineCap;
65168    ctx.miterLimit = this.strokeMiterLimit;
65169    ctx.lineJoin = this.strokeLineJoin;
65170    ctx.setLineDash(this.strokeDashArray || []);
65171  },
65172
65173  /**
65174   * Sets the transformation on given context
65175   * @param {RenderingContext2d} ctx context to render on
65176   * @private
65177   */
65178  _saveAndTransform: function(ctx) {
65179    var v = this.canvas.viewportTransform;
65180    ctx.save();
65181    ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
65182  },
65183
65184  /**
65185   * Sets brush shadow styles
65186   * @private
65187   */
65188  _setShadow: function() {
65189    if (!this.shadow) {
65190      return;
65191    }
65192
65193    var canvas = this.canvas,
65194        shadow = this.shadow,
65195        ctx = canvas.contextTop,
65196        zoom = canvas.getZoom();
65197    if (canvas && canvas._isRetinaScaling()) {
65198      zoom *= fabric.devicePixelRatio;
65199    }
65200
65201    ctx.shadowColor = shadow.color;
65202    ctx.shadowBlur = shadow.blur * zoom;
65203    ctx.shadowOffsetX = shadow.offsetX * zoom;
65204    ctx.shadowOffsetY = shadow.offsetY * zoom;
65205  },
65206
65207  needsFullRender: function() {
65208    var color = new fabric.Color(this.color);
65209    return color.getAlpha() < 1 || !!this.shadow;
65210  },
65211
65212  /**
65213   * Removes brush shadow styles
65214   * @private
65215   */
65216  _resetShadow: function() {
65217    var ctx = this.canvas.contextTop;
65218
65219    ctx.shadowColor = '';
65220    ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;
65221  },
65222
65223  /**
65224   * Check is pointer is outside canvas boundaries
65225   * @param {Object} pointer
65226   * @private
65227  */
65228  _isOutSideCanvas: function(pointer) {
65229    return pointer.x < 0 || pointer.x > this.canvas.getWidth() || pointer.y < 0 || pointer.y > this.canvas.getHeight();
65230  }
65231});
65232
65233
65234(function() {
65235  /**
65236   * PencilBrush class
65237   * @class fabric.PencilBrush
65238   * @extends fabric.BaseBrush
65239   */
65240  fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.PencilBrush.prototype */ {
65241
65242    /**
65243     * Discard points that are less than `decimate` pixel distant from each other
65244     * @type Number
65245     * @default 0.4
65246     */
65247    decimate: 0.4,
65248
65249    /**
65250     * Constructor
65251     * @param {fabric.Canvas} canvas
65252     * @return {fabric.PencilBrush} Instance of a pencil brush
65253     */
65254    initialize: function(canvas) {
65255      this.canvas = canvas;
65256      this._points = [];
65257    },
65258
65259    /**
65260     * Invoked inside on mouse down and mouse move
65261     * @param {Object} pointer
65262     */
65263    _drawSegment: function (ctx, p1, p2) {
65264      var midPoint = p1.midPointFrom(p2);
65265      ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
65266      return midPoint;
65267    },
65268
65269    /**
65270     * Invoked on mouse down
65271     * @param {Object} pointer
65272     */
65273    onMouseDown: function(pointer, options) {
65274      if (!this.canvas._isMainEvent(options.e)) {
65275        return;
65276      }
65277      this._prepareForDrawing(pointer);
65278      // capture coordinates immediately
65279      // this allows to draw dots (when movement never occurs)
65280      this._captureDrawingPath(pointer);
65281      this._render();
65282    },
65283
65284    /**
65285     * Invoked on mouse move
65286     * @param {Object} pointer
65287     */
65288    onMouseMove: function(pointer, options) {
65289      if (!this.canvas._isMainEvent(options.e)) {
65290        return;
65291      }
65292      if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {
65293        return;
65294      }
65295      if (this._captureDrawingPath(pointer) && this._points.length > 1) {
65296        if (this.needsFullRender()) {
65297          // redraw curve
65298          // clear top canvas
65299          this.canvas.clearContext(this.canvas.contextTop);
65300          this._render();
65301        }
65302        else {
65303          var points = this._points, length = points.length, ctx = this.canvas.contextTop;
65304          // draw the curve update
65305          this._saveAndTransform(ctx);
65306          if (this.oldEnd) {
65307            ctx.beginPath();
65308            ctx.moveTo(this.oldEnd.x, this.oldEnd.y);
65309          }
65310          this.oldEnd = this._drawSegment(ctx, points[length - 2], points[length - 1], true);
65311          ctx.stroke();
65312          ctx.restore();
65313        }
65314      }
65315    },
65316
65317    /**
65318     * Invoked on mouse up
65319     */
65320    onMouseUp: function(options) {
65321      if (!this.canvas._isMainEvent(options.e)) {
65322        return true;
65323      }
65324      this.oldEnd = undefined;
65325      this._finalizeAndAddPath();
65326      return false;
65327    },
65328
65329    /**
65330     * @private
65331     * @param {Object} pointer Actual mouse position related to the canvas.
65332     */
65333    _prepareForDrawing: function(pointer) {
65334
65335      var p = new fabric.Point(pointer.x, pointer.y);
65336
65337      this._reset();
65338      this._addPoint(p);
65339      this.canvas.contextTop.moveTo(p.x, p.y);
65340    },
65341
65342    /**
65343     * @private
65344     * @param {fabric.Point} point Point to be added to points array
65345     */
65346    _addPoint: function(point) {
65347      if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) {
65348        return false;
65349      }
65350      this._points.push(point);
65351      return true;
65352    },
65353
65354    /**
65355     * Clear points array and set contextTop canvas style.
65356     * @private
65357     */
65358    _reset: function() {
65359      this._points = [];
65360      this._setBrushStyles();
65361      this._setShadow();
65362    },
65363
65364    /**
65365     * @private
65366     * @param {Object} pointer Actual mouse position related to the canvas.
65367     */
65368    _captureDrawingPath: function(pointer) {
65369      var pointerPoint = new fabric.Point(pointer.x, pointer.y);
65370      return this._addPoint(pointerPoint);
65371    },
65372
65373    /**
65374     * Draw a smooth path on the topCanvas using quadraticCurveTo
65375     * @private
65376     */
65377    _render: function() {
65378      var ctx  = this.canvas.contextTop, i, len,
65379          p1 = this._points[0],
65380          p2 = this._points[1];
65381
65382      this._saveAndTransform(ctx);
65383      ctx.beginPath();
65384      //if we only have 2 points in the path and they are the same
65385      //it means that the user only clicked the canvas without moving the mouse
65386      //then we should be drawing a dot. A path isn't drawn between two identical dots
65387      //that's why we set them apart a bit
65388      if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {
65389        var width = this.width / 1000;
65390        p1 = new fabric.Point(p1.x, p1.y);
65391        p2 = new fabric.Point(p2.x, p2.y);
65392        p1.x -= width;
65393        p2.x += width;
65394      }
65395      ctx.moveTo(p1.x, p1.y);
65396
65397      for (i = 1, len = this._points.length; i < len; i++) {
65398        // we pick the point between pi + 1 & pi + 2 as the
65399        // end point and p1 as our control point.
65400        this._drawSegment(ctx, p1, p2);
65401        p1 = this._points[i];
65402        p2 = this._points[i + 1];
65403      }
65404      // Draw last line as a straight line while
65405      // we wait for the next point to be able to calculate
65406      // the bezier control point
65407      ctx.lineTo(p1.x, p1.y);
65408      ctx.stroke();
65409      ctx.restore();
65410    },
65411
65412    /**
65413     * Converts points to SVG path
65414     * @param {Array} points Array of points
65415     * @return {(string|number)[][]} SVG path commands
65416     */
65417    convertPointsToSVGPath: function (points) {
65418      var correction = this.width / 1000;
65419      return fabric.util.getSmoothPathFromPoints(points, correction);
65420    },
65421
65422    /**
65423     * @private
65424     * @param {(string|number)[][]} pathData SVG path commands
65425     * @returns {boolean}
65426     */
65427    _isEmptySVGPath: function (pathData) {
65428      var pathString = fabric.util.joinPath(pathData);
65429      return pathString === 'M 0 0 Q 0 0 0 0 L 0 0';
65430    },
65431
65432    /**
65433     * Creates fabric.Path object to add on canvas
65434     * @param {(string|number)[][]} pathData Path data
65435     * @return {fabric.Path} Path to add on canvas
65436     */
65437    createPath: function(pathData) {
65438      var path = new fabric.Path(pathData, {
65439        fill: null,
65440        stroke: this.color,
65441        strokeWidth: this.width,
65442        strokeLineCap: this.strokeLineCap,
65443        strokeMiterLimit: this.strokeMiterLimit,
65444        strokeLineJoin: this.strokeLineJoin,
65445        strokeDashArray: this.strokeDashArray,
65446      });
65447      if (this.shadow) {
65448        this.shadow.affectStroke = true;
65449        path.shadow = new fabric.Shadow(this.shadow);
65450      }
65451
65452      return path;
65453    },
65454
65455    /**
65456     * Decimate points array with the decimate value
65457     */
65458    decimatePoints: function(points, distance) {
65459      if (points.length <= 2) {
65460        return points;
65461      }
65462      var zoom = this.canvas.getZoom(), adjustedDistance = Math.pow(distance / zoom, 2),
65463          i, l = points.length - 1, lastPoint = points[0], newPoints = [lastPoint],
65464          cDistance;
65465      for (i = 1; i < l - 1; i++) {
65466        cDistance = Math.pow(lastPoint.x - points[i].x, 2) + Math.pow(lastPoint.y - points[i].y, 2);
65467        if (cDistance >= adjustedDistance) {
65468          lastPoint = points[i];
65469          newPoints.push(lastPoint);
65470        }
65471      }
65472      /**
65473       * Add the last point from the original line to the end of the array.
65474       * This ensures decimate doesn't delete the last point on the line, and ensures the line is > 1 point.
65475       */
65476      newPoints.push(points[l]);
65477      return newPoints;
65478    },
65479
65480    /**
65481     * On mouseup after drawing the path on contextTop canvas
65482     * we use the points captured to create an new fabric path object
65483     * and add it to the fabric canvas.
65484     */
65485    _finalizeAndAddPath: function() {
65486      var ctx = this.canvas.contextTop;
65487      ctx.closePath();
65488      if (this.decimate) {
65489        this._points = this.decimatePoints(this._points, this.decimate);
65490      }
65491      var pathData = this.convertPointsToSVGPath(this._points);
65492      if (this._isEmptySVGPath(pathData)) {
65493        // do not create 0 width/height paths, as they are
65494        // rendered inconsistently across browsers
65495        // Firefox 4, for example, renders a dot,
65496        // whereas Chrome 10 renders nothing
65497        this.canvas.requestRenderAll();
65498        return;
65499      }
65500
65501      var path = this.createPath(pathData);
65502      this.canvas.clearContext(this.canvas.contextTop);
65503      this.canvas.fire('before:path:created', { path: path });
65504      this.canvas.add(path);
65505      this.canvas.requestRenderAll();
65506      path.setCoords();
65507      this._resetShadow();
65508
65509
65510      // fire event 'path' created
65511      this.canvas.fire('path:created', { path: path });
65512    }
65513  });
65514})();
65515
65516
65517/**
65518 * CircleBrush class
65519 * @class fabric.CircleBrush
65520 */
65521fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.CircleBrush.prototype */ {
65522
65523  /**
65524   * Width of a brush
65525   * @type Number
65526   * @default
65527   */
65528  width: 10,
65529
65530  /**
65531   * Constructor
65532   * @param {fabric.Canvas} canvas
65533   * @return {fabric.CircleBrush} Instance of a circle brush
65534   */
65535  initialize: function(canvas) {
65536    this.canvas = canvas;
65537    this.points = [];
65538  },
65539
65540  /**
65541   * Invoked inside on mouse down and mouse move
65542   * @param {Object} pointer
65543   */
65544  drawDot: function(pointer) {
65545    var point = this.addPoint(pointer),
65546        ctx = this.canvas.contextTop;
65547    this._saveAndTransform(ctx);
65548    this.dot(ctx, point);
65549    ctx.restore();
65550  },
65551
65552  dot: function(ctx, point) {
65553    ctx.fillStyle = point.fill;
65554    ctx.beginPath();
65555    ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false);
65556    ctx.closePath();
65557    ctx.fill();
65558  },
65559
65560  /**
65561   * Invoked on mouse down
65562   */
65563  onMouseDown: function(pointer) {
65564    this.points.length = 0;
65565    this.canvas.clearContext(this.canvas.contextTop);
65566    this._setShadow();
65567    this.drawDot(pointer);
65568  },
65569
65570  /**
65571   * Render the full state of the brush
65572   * @private
65573   */
65574  _render: function() {
65575    var ctx  = this.canvas.contextTop, i, len,
65576        points = this.points;
65577    this._saveAndTransform(ctx);
65578    for (i = 0, len = points.length; i < len; i++) {
65579      this.dot(ctx, points[i]);
65580    }
65581    ctx.restore();
65582  },
65583
65584  /**
65585   * Invoked on mouse move
65586   * @param {Object} pointer
65587   */
65588  onMouseMove: function(pointer) {
65589    if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {
65590      return;
65591    }
65592    if (this.needsFullRender()) {
65593      this.canvas.clearContext(this.canvas.contextTop);
65594      this.addPoint(pointer);
65595      this._render();
65596    }
65597    else {
65598      this.drawDot(pointer);
65599    }
65600  },
65601
65602  /**
65603   * Invoked on mouse up
65604   */
65605  onMouseUp: function() {
65606    var originalRenderOnAddRemove = this.canvas.renderOnAddRemove, i, len;
65607    this.canvas.renderOnAddRemove = false;
65608
65609    var circles = [];
65610
65611    for (i = 0, len = this.points.length; i < len; i++) {
65612      var point = this.points[i],
65613          circle = new fabric.Circle({
65614            radius: point.radius,
65615            left: point.x,
65616            top: point.y,
65617            originX: 'center',
65618            originY: 'center',
65619            fill: point.fill
65620          });
65621
65622      this.shadow && (circle.shadow = new fabric.Shadow(this.shadow));
65623
65624      circles.push(circle);
65625    }
65626    var group = new fabric.Group(circles);
65627    group.canvas = this.canvas;
65628
65629    this.canvas.fire('before:path:created', { path: group });
65630    this.canvas.add(group);
65631    this.canvas.fire('path:created', { path: group });
65632
65633    this.canvas.clearContext(this.canvas.contextTop);
65634    this._resetShadow();
65635    this.canvas.renderOnAddRemove = originalRenderOnAddRemove;
65636    this.canvas.requestRenderAll();
65637  },
65638
65639  /**
65640   * @param {Object} pointer
65641   * @return {fabric.Point} Just added pointer point
65642   */
65643  addPoint: function(pointer) {
65644    var pointerPoint = new fabric.Point(pointer.x, pointer.y),
65645
65646        circleRadius = fabric.util.getRandomInt(
65647          Math.max(0, this.width - 20), this.width + 20) / 2,
65648
65649        circleColor = new fabric.Color(this.color)
65650          .setAlpha(fabric.util.getRandomInt(0, 100) / 100)
65651          .toRgba();
65652
65653    pointerPoint.radius = circleRadius;
65654    pointerPoint.fill = circleColor;
65655
65656    this.points.push(pointerPoint);
65657
65658    return pointerPoint;
65659  }
65660});
65661
65662
65663/**
65664 * SprayBrush class
65665 * @class fabric.SprayBrush
65666 */
65667fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric.SprayBrush.prototype */ {
65668
65669  /**
65670   * Width of a spray
65671   * @type Number
65672   * @default
65673   */
65674  width:              10,
65675
65676  /**
65677   * Density of a spray (number of dots per chunk)
65678   * @type Number
65679   * @default
65680   */
65681  density:            20,
65682
65683  /**
65684   * Width of spray dots
65685   * @type Number
65686   * @default
65687   */
65688  dotWidth:           1,
65689
65690  /**
65691   * Width variance of spray dots
65692   * @type Number
65693   * @default
65694   */
65695  dotWidthVariance:   1,
65696
65697  /**
65698   * Whether opacity of a dot should be random
65699   * @type Boolean
65700   * @default
65701   */
65702  randomOpacity:        false,
65703
65704  /**
65705   * Whether overlapping dots (rectangles) should be removed (for performance reasons)
65706   * @type Boolean
65707   * @default
65708   */
65709  optimizeOverlapping:  true,
65710
65711  /**
65712   * Constructor
65713   * @param {fabric.Canvas} canvas
65714   * @return {fabric.SprayBrush} Instance of a spray brush
65715   */
65716  initialize: function(canvas) {
65717    this.canvas = canvas;
65718    this.sprayChunks = [];
65719  },
65720
65721  /**
65722   * Invoked on mouse down
65723   * @param {Object} pointer
65724   */
65725  onMouseDown: function(pointer) {
65726    this.sprayChunks.length = 0;
65727    this.canvas.clearContext(this.canvas.contextTop);
65728    this._setShadow();
65729
65730    this.addSprayChunk(pointer);
65731    this.render(this.sprayChunkPoints);
65732  },
65733
65734  /**
65735   * Invoked on mouse move
65736   * @param {Object} pointer
65737   */
65738  onMouseMove: function(pointer) {
65739    if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {
65740      return;
65741    }
65742    this.addSprayChunk(pointer);
65743    this.render(this.sprayChunkPoints);
65744  },
65745
65746  /**
65747   * Invoked on mouse up
65748   */
65749  onMouseUp: function() {
65750    var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;
65751    this.canvas.renderOnAddRemove = false;
65752
65753    var rects = [];
65754
65755    for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {
65756      var sprayChunk = this.sprayChunks[i];
65757
65758      for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) {
65759
65760        var rect = new fabric.Rect({
65761          width: sprayChunk[j].width,
65762          height: sprayChunk[j].width,
65763          left: sprayChunk[j].x + 1,
65764          top: sprayChunk[j].y + 1,
65765          originX: 'center',
65766          originY: 'center',
65767          fill: this.color
65768        });
65769        rects.push(rect);
65770      }
65771    }
65772
65773    if (this.optimizeOverlapping) {
65774      rects = this._getOptimizedRects(rects);
65775    }
65776
65777    var group = new fabric.Group(rects);
65778    this.shadow && group.set('shadow', new fabric.Shadow(this.shadow));
65779    this.canvas.fire('before:path:created', { path: group });
65780    this.canvas.add(group);
65781    this.canvas.fire('path:created', { path: group });
65782
65783    this.canvas.clearContext(this.canvas.contextTop);
65784    this._resetShadow();
65785    this.canvas.renderOnAddRemove = originalRenderOnAddRemove;
65786    this.canvas.requestRenderAll();
65787  },
65788
65789  /**
65790   * @private
65791   * @param {Array} rects
65792   */
65793  _getOptimizedRects: function(rects) {
65794
65795    // avoid creating duplicate rects at the same coordinates
65796    var uniqueRects = { }, key, i, len;
65797
65798    for (i = 0, len = rects.length; i < len; i++) {
65799      key = rects[i].left + '' + rects[i].top;
65800      if (!uniqueRects[key]) {
65801        uniqueRects[key] = rects[i];
65802      }
65803    }
65804    var uniqueRectsArray = [];
65805    for (key in uniqueRects) {
65806      uniqueRectsArray.push(uniqueRects[key]);
65807    }
65808
65809    return uniqueRectsArray;
65810  },
65811
65812  /**
65813   * Render new chunk of spray brush
65814   */
65815  render: function(sprayChunk) {
65816    var ctx = this.canvas.contextTop, i, len;
65817    ctx.fillStyle = this.color;
65818
65819    this._saveAndTransform(ctx);
65820
65821    for (i = 0, len = sprayChunk.length; i < len; i++) {
65822      var point = sprayChunk[i];
65823      if (typeof point.opacity !== 'undefined') {
65824        ctx.globalAlpha = point.opacity;
65825      }
65826      ctx.fillRect(point.x, point.y, point.width, point.width);
65827    }
65828    ctx.restore();
65829  },
65830
65831  /**
65832   * Render all spray chunks
65833   */
65834  _render: function() {
65835    var ctx = this.canvas.contextTop, i, ilen;
65836    ctx.fillStyle = this.color;
65837
65838    this._saveAndTransform(ctx);
65839
65840    for (i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {
65841      this.render(this.sprayChunks[i]);
65842    }
65843    ctx.restore();
65844  },
65845
65846  /**
65847   * @param {Object} pointer
65848   */
65849  addSprayChunk: function(pointer) {
65850    this.sprayChunkPoints = [];
65851
65852    var x, y, width, radius = this.width / 2, i;
65853
65854    for (i = 0; i < this.density; i++) {
65855
65856      x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius);
65857      y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius);
65858
65859      if (this.dotWidthVariance) {
65860        width = fabric.util.getRandomInt(
65861          // bottom clamp width to 1
65862          Math.max(1, this.dotWidth - this.dotWidthVariance),
65863          this.dotWidth + this.dotWidthVariance);
65864      }
65865      else {
65866        width = this.dotWidth;
65867      }
65868
65869      var point = new fabric.Point(x, y);
65870      point.width = width;
65871
65872      if (this.randomOpacity) {
65873        point.opacity = fabric.util.getRandomInt(0, 100) / 100;
65874      }
65875
65876      this.sprayChunkPoints.push(point);
65877    }
65878
65879    this.sprayChunks.push(this.sprayChunkPoints);
65880  }
65881});
65882
65883
65884/**
65885 * PatternBrush class
65886 * @class fabric.PatternBrush
65887 * @extends fabric.BaseBrush
65888 */
65889fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fabric.PatternBrush.prototype */ {
65890
65891  getPatternSrc: function() {
65892
65893    var dotWidth = 20,
65894        dotDistance = 5,
65895        patternCanvas = fabric.util.createCanvasElement(),
65896        patternCtx = patternCanvas.getContext('2d');
65897
65898    patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;
65899
65900    patternCtx.fillStyle = this.color;
65901    patternCtx.beginPath();
65902    patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false);
65903    patternCtx.closePath();
65904    patternCtx.fill();
65905
65906    return patternCanvas;
65907  },
65908
65909  getPatternSrcFunction: function() {
65910    return String(this.getPatternSrc).replace('this.color', '"' + this.color + '"');
65911  },
65912
65913  /**
65914   * Creates "pattern" instance property
65915   */
65916  getPattern: function() {
65917    return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), 'repeat');
65918  },
65919
65920  /**
65921   * Sets brush styles
65922   */
65923  _setBrushStyles: function() {
65924    this.callSuper('_setBrushStyles');
65925    this.canvas.contextTop.strokeStyle = this.getPattern();
65926  },
65927
65928  /**
65929   * Creates path
65930   */
65931  createPath: function(pathData) {
65932    var path = this.callSuper('createPath', pathData),
65933        topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);
65934
65935    path.stroke = new fabric.Pattern({
65936      source: this.source || this.getPatternSrcFunction(),
65937      offsetX: -topLeft.x,
65938      offsetY: -topLeft.y
65939    });
65940    return path;
65941  }
65942});
65943
65944
65945(function() {
65946
65947  var getPointer = fabric.util.getPointer,
65948      degreesToRadians = fabric.util.degreesToRadians,
65949      isTouchEvent = fabric.util.isTouchEvent;
65950
65951  /**
65952   * Canvas class
65953   * @class fabric.Canvas
65954   * @extends fabric.StaticCanvas
65955   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}
65956   * @see {@link fabric.Canvas#initialize} for constructor definition
65957   *
65958   * @fires object:modified at the end of a transform or any change when statefull is true
65959   * @fires object:rotating while an object is being rotated from the control
65960   * @fires object:scaling while an object is being scaled by controls
65961   * @fires object:moving while an object is being dragged
65962   * @fires object:skewing while an object is being skewed from the controls
65963   *
65964   * @fires before:transform before a transform is is started
65965   * @fires before:selection:cleared
65966   * @fires selection:cleared
65967   * @fires selection:updated
65968   * @fires selection:created
65969   *
65970   * @fires path:created after a drawing operation ends and the path is added
65971   * @fires mouse:down
65972   * @fires mouse:move
65973   * @fires mouse:up
65974   * @fires mouse:down:before  on mouse down, before the inner fabric logic runs
65975   * @fires mouse:move:before on mouse move, before the inner fabric logic runs
65976   * @fires mouse:up:before on mouse up, before the inner fabric logic runs
65977   * @fires mouse:over
65978   * @fires mouse:out
65979   * @fires mouse:dblclick whenever a native dbl click event fires on the canvas.
65980   *
65981   * @fires dragover
65982   * @fires dragenter
65983   * @fires dragleave
65984   * @fires drop
65985   * @fires after:render at the end of the render process, receives the context in the callback
65986   * @fires before:render at start the render process, receives the context in the callback
65987   *
65988   * the following events are deprecated:
65989   * @fires object:rotated at the end of a rotation transform
65990   * @fires object:scaled at the end of a scale transform
65991   * @fires object:moved at the end of translation transform
65992   * @fires object:skewed at the end of a skew transform
65993   */
65994  fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ {
65995
65996    /**
65997     * Constructor
65998     * @param {HTMLElement | String} el &lt;canvas> element to initialize instance on
65999     * @param {Object} [options] Options object
66000     * @return {Object} thisArg
66001     */
66002    initialize: function(el, options) {
66003      options || (options = { });
66004      this.renderAndResetBound = this.renderAndReset.bind(this);
66005      this.requestRenderAllBound = this.requestRenderAll.bind(this);
66006      this._initStatic(el, options);
66007      this._initInteractive();
66008      this._createCacheCanvas();
66009    },
66010
66011    /**
66012     * When true, objects can be transformed by one side (unproportionally)
66013     * when dragged on the corners that normally would not do that.
66014     * @type Boolean
66015     * @default
66016     * @since fabric 4.0 // changed name and default value
66017     */
66018    uniformScaling:      true,
66019
66020    /**
66021     * Indicates which key switches uniform scaling.
66022     * values: 'altKey', 'shiftKey', 'ctrlKey'.
66023     * If `null` or 'none' or any other string that is not a modifier key
66024     * feature is disabled.
66025     * totally wrong named. this sounds like `uniform scaling`
66026     * if Canvas.uniformScaling is true, pressing this will set it to false
66027     * and viceversa.
66028     * @since 1.6.2
66029     * @type String
66030     * @default
66031     */
66032    uniScaleKey:           'shiftKey',
66033
66034    /**
66035     * When true, objects use center point as the origin of scale transformation.
66036     * <b>Backwards incompatibility note:</b> This property replaces "centerTransform" (Boolean).
66037     * @since 1.3.4
66038     * @type Boolean
66039     * @default
66040     */
66041    centeredScaling:        false,
66042
66043    /**
66044     * When true, objects use center point as the origin of rotate transformation.
66045     * <b>Backwards incompatibility note:</b> This property replaces "centerTransform" (Boolean).
66046     * @since 1.3.4
66047     * @type Boolean
66048     * @default
66049     */
66050    centeredRotation:       false,
66051
66052    /**
66053     * Indicates which key enable centered Transform
66054     * values: 'altKey', 'shiftKey', 'ctrlKey'.
66055     * If `null` or 'none' or any other string that is not a modifier key
66056     * feature is disabled feature disabled.
66057     * @since 1.6.2
66058     * @type String
66059     * @default
66060     */
66061    centeredKey:           'altKey',
66062
66063    /**
66064     * Indicates which key enable alternate action on corner
66065     * values: 'altKey', 'shiftKey', 'ctrlKey'.
66066     * If `null` or 'none' or any other string that is not a modifier key
66067     * feature is disabled feature disabled.
66068     * @since 1.6.2
66069     * @type String
66070     * @default
66071     */
66072    altActionKey:           'shiftKey',
66073
66074    /**
66075     * Indicates that canvas is interactive. This property should not be changed.
66076     * @type Boolean
66077     * @default
66078     */
66079    interactive:            true,
66080
66081    /**
66082     * Indicates whether group selection should be enabled
66083     * @type Boolean
66084     * @default
66085     */
66086    selection:              true,
66087
66088    /**
66089     * Indicates which key or keys enable multiple click selection
66090     * Pass value as a string or array of strings
66091     * values: 'altKey', 'shiftKey', 'ctrlKey'.
66092     * If `null` or empty or containing any other string that is not a modifier key
66093     * feature is disabled.
66094     * @since 1.6.2
66095     * @type String|Array
66096     * @default
66097     */
66098    selectionKey:           'shiftKey',
66099
66100    /**
66101     * Indicates which key enable alternative selection
66102     * in case of target overlapping with active object
66103     * values: 'altKey', 'shiftKey', 'ctrlKey'.
66104     * For a series of reason that come from the general expectations on how
66105     * things should work, this feature works only for preserveObjectStacking true.
66106     * If `null` or 'none' or any other string that is not a modifier key
66107     * feature is disabled.
66108     * @since 1.6.5
66109     * @type null|String
66110     * @default
66111     */
66112    altSelectionKey:           null,
66113
66114    /**
66115     * Color of selection
66116     * @type String
66117     * @default
66118     */
66119    selectionColor:         'rgba(100, 100, 255, 0.3)', // blue
66120
66121    /**
66122     * Default dash array pattern
66123     * If not empty the selection border is dashed
66124     * @type Array
66125     */
66126    selectionDashArray:     [],
66127
66128    /**
66129     * Color of the border of selection (usually slightly darker than color of selection itself)
66130     * @type String
66131     * @default
66132     */
66133    selectionBorderColor:   'rgba(255, 255, 255, 0.3)',
66134
66135    /**
66136     * Width of a line used in object/group selection
66137     * @type Number
66138     * @default
66139     */
66140    selectionLineWidth:     1,
66141
66142    /**
66143     * Select only shapes that are fully contained in the dragged selection rectangle.
66144     * @type Boolean
66145     * @default
66146     */
66147    selectionFullyContained: false,
66148
66149    /**
66150     * Default cursor value used when hovering over an object on canvas
66151     * @type String
66152     * @default
66153     */
66154    hoverCursor:            'move',
66155
66156    /**
66157     * Default cursor value used when moving an object on canvas
66158     * @type String
66159     * @default
66160     */
66161    moveCursor:             'move',
66162
66163    /**
66164     * Default cursor value used for the entire canvas
66165     * @type String
66166     * @default
66167     */
66168    defaultCursor:          'default',
66169
66170    /**
66171     * Cursor value used during free drawing
66172     * @type String
66173     * @default
66174     */
66175    freeDrawingCursor:      'crosshair',
66176
66177    /**
66178     * Cursor value used for rotation point
66179     * @type String
66180     * @default
66181     */
66182    rotationCursor:         'crosshair',
66183
66184    /**
66185     * Cursor value used for disabled elements ( corners with disabled action )
66186     * @type String
66187     * @since 2.0.0
66188     * @default
66189     */
66190    notAllowedCursor:         'not-allowed',
66191
66192    /**
66193     * Default element class that's given to wrapper (div) element of canvas
66194     * @type String
66195     * @default
66196     */
66197    containerClass:         'canvas-container',
66198
66199    /**
66200     * When true, object detection happens on per-pixel basis rather than on per-bounding-box
66201     * @type Boolean
66202     * @default
66203     */
66204    perPixelTargetFind:     false,
66205
66206    /**
66207     * Number of pixels around target pixel to tolerate (consider active) during object detection
66208     * @type Number
66209     * @default
66210     */
66211    targetFindTolerance:    0,
66212
66213    /**
66214     * When true, target detection is skipped. Target detection will return always undefined.
66215     * click selection won't work anymore, events will fire with no targets.
66216     * if something is selected before setting it to true, it will be deselected at the first click.
66217     * area selection will still work. check the `selection` property too.
66218     * if you deactivate both, you should look into staticCanvas.
66219     * @type Boolean
66220     * @default
66221     */
66222    skipTargetFind:         false,
66223
66224    /**
66225     * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing.
66226     * After mousedown, mousemove creates a shape,
66227     * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas.
66228     * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing}
66229     * @type Boolean
66230     * @default
66231     */
66232    isDrawingMode:          false,
66233
66234    /**
66235     * Indicates whether objects should remain in current stack position when selected.
66236     * When false objects are brought to top and rendered as part of the selection group
66237     * @type Boolean
66238     * @default
66239     */
66240    preserveObjectStacking: false,
66241
66242    /**
66243     * Indicates the angle that an object will lock to while rotating.
66244     * @type Number
66245     * @since 1.6.7
66246     * @default
66247     */
66248    snapAngle: 0,
66249
66250    /**
66251     * Indicates the distance from the snapAngle the rotation will lock to the snapAngle.
66252     * When `null`, the snapThreshold will default to the snapAngle.
66253     * @type null|Number
66254     * @since 1.6.7
66255     * @default
66256     */
66257    snapThreshold: null,
66258
66259    /**
66260     * Indicates if the right click on canvas can output the context menu or not
66261     * @type Boolean
66262     * @since 1.6.5
66263     * @default
66264     */
66265    stopContextMenu: false,
66266
66267    /**
66268     * Indicates if the canvas can fire right click events
66269     * @type Boolean
66270     * @since 1.6.5
66271     * @default
66272     */
66273    fireRightClick: false,
66274
66275    /**
66276     * Indicates if the canvas can fire middle click events
66277     * @type Boolean
66278     * @since 1.7.8
66279     * @default
66280     */
66281    fireMiddleClick: false,
66282
66283    /**
66284     * Keep track of the subTargets for Mouse Events
66285     * @type fabric.Object[]
66286     */
66287    targets: [],
66288
66289    /**
66290     * Keep track of the hovered target
66291     * @type fabric.Object
66292     * @private
66293     */
66294    _hoveredTarget: null,
66295
66296    /**
66297     * hold the list of nested targets hovered
66298     * @type fabric.Object[]
66299     * @private
66300     */
66301    _hoveredTargets: [],
66302
66303    /**
66304     * @private
66305     */
66306    _initInteractive: function() {
66307      this._currentTransform = null;
66308      this._groupSelector = null;
66309      this._initWrapperElement();
66310      this._createUpperCanvas();
66311      this._initEventListeners();
66312
66313      this._initRetinaScaling();
66314
66315      this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this);
66316
66317      this.calcOffset();
66318    },
66319
66320    /**
66321     * Divides objects in two groups, one to render immediately
66322     * and one to render as activeGroup.
66323     * @return {Array} objects to render immediately and pushes the other in the activeGroup.
66324     */
66325    _chooseObjectsToRender: function() {
66326      var activeObjects = this.getActiveObjects(),
66327          object, objsToRender, activeGroupObjects;
66328
66329      if (activeObjects.length > 0 && !this.preserveObjectStacking) {
66330        objsToRender = [];
66331        activeGroupObjects = [];
66332        for (var i = 0, length = this._objects.length; i < length; i++) {
66333          object = this._objects[i];
66334          if (activeObjects.indexOf(object) === -1 ) {
66335            objsToRender.push(object);
66336          }
66337          else {
66338            activeGroupObjects.push(object);
66339          }
66340        }
66341        if (activeObjects.length > 1) {
66342          this._activeObject._objects = activeGroupObjects;
66343        }
66344        objsToRender.push.apply(objsToRender, activeGroupObjects);
66345      }
66346      else {
66347        objsToRender = this._objects;
66348      }
66349      return objsToRender;
66350    },
66351
66352    /**
66353     * Renders both the top canvas and the secondary container canvas.
66354     * @return {fabric.Canvas} instance
66355     * @chainable
66356     */
66357    renderAll: function () {
66358      if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {
66359        this.clearContext(this.contextTop);
66360        this.contextTopDirty = false;
66361      }
66362      if (this.hasLostContext) {
66363        this.renderTopLayer(this.contextTop);
66364      }
66365      var canvasToDrawOn = this.contextContainer;
66366      this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());
66367      return this;
66368    },
66369
66370    renderTopLayer: function(ctx) {
66371      ctx.save();
66372      if (this.isDrawingMode && this._isCurrentlyDrawing) {
66373        this.freeDrawingBrush && this.freeDrawingBrush._render();
66374        this.contextTopDirty = true;
66375      }
66376      // we render the top context - last object
66377      if (this.selection && this._groupSelector) {
66378        this._drawSelection(ctx);
66379        this.contextTopDirty = true;
66380      }
66381      ctx.restore();
66382    },
66383
66384    /**
66385     * Method to render only the top canvas.
66386     * Also used to render the group selection box.
66387     * @return {fabric.Canvas} thisArg
66388     * @chainable
66389     */
66390    renderTop: function () {
66391      var ctx = this.contextTop;
66392      this.clearContext(ctx);
66393      this.renderTopLayer(ctx);
66394      this.fire('after:render');
66395      return this;
66396    },
66397
66398    /**
66399     * @private
66400     */
66401    _normalizePointer: function (object, pointer) {
66402      var m = object.calcTransformMatrix(),
66403          invertedM = fabric.util.invertTransform(m),
66404          vptPointer = this.restorePointerVpt(pointer);
66405      return fabric.util.transformPoint(vptPointer, invertedM);
66406    },
66407
66408    /**
66409     * Returns true if object is transparent at a certain location
66410     * @param {fabric.Object} target Object to check
66411     * @param {Number} x Left coordinate
66412     * @param {Number} y Top coordinate
66413     * @return {Boolean}
66414     */
66415    isTargetTransparent: function (target, x, y) {
66416      // in case the target is the activeObject, we cannot execute this optimization
66417      // because we need to draw controls too.
66418      if (target.shouldCache() && target._cacheCanvas && target !== this._activeObject) {
66419        var normalizedPointer = this._normalizePointer(target, {x: x, y: y}),
66420            targetRelativeX = Math.max(target.cacheTranslationX + (normalizedPointer.x * target.zoomX), 0),
66421            targetRelativeY = Math.max(target.cacheTranslationY + (normalizedPointer.y * target.zoomY), 0);
66422
66423        var isTransparent = fabric.util.isTransparent(
66424          target._cacheContext, Math.round(targetRelativeX), Math.round(targetRelativeY), this.targetFindTolerance);
66425
66426        return isTransparent;
66427      }
66428
66429      var ctx = this.contextCache,
66430          originalColor = target.selectionBackgroundColor, v = this.viewportTransform;
66431
66432      target.selectionBackgroundColor = '';
66433
66434      this.clearContext(ctx);
66435
66436      ctx.save();
66437      ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
66438      target.render(ctx);
66439      ctx.restore();
66440
66441      target.selectionBackgroundColor = originalColor;
66442
66443      var isTransparent = fabric.util.isTransparent(
66444        ctx, x, y, this.targetFindTolerance);
66445
66446      return isTransparent;
66447    },
66448
66449    /**
66450     * takes an event and determines if selection key has been pressed
66451     * @private
66452     * @param {Event} e Event object
66453     */
66454    _isSelectionKeyPressed: function(e) {
66455      var selectionKeyPressed = false;
66456
66457      if (Object.prototype.toString.call(this.selectionKey) === '[object Array]') {
66458        selectionKeyPressed = !!this.selectionKey.find(function(key) { return e[key] === true; });
66459      }
66460      else {
66461        selectionKeyPressed = e[this.selectionKey];
66462      }
66463
66464      return selectionKeyPressed;
66465    },
66466
66467    /**
66468     * @private
66469     * @param {Event} e Event object
66470     * @param {fabric.Object} target
66471     */
66472    _shouldClearSelection: function (e, target) {
66473      var activeObjects = this.getActiveObjects(),
66474          activeObject = this._activeObject;
66475
66476      return (
66477        !target
66478        ||
66479        (target &&
66480          activeObject &&
66481          activeObjects.length > 1 &&
66482          activeObjects.indexOf(target) === -1 &&
66483          activeObject !== target &&
66484          !this._isSelectionKeyPressed(e))
66485        ||
66486        (target && !target.evented)
66487        ||
66488        (target &&
66489          !target.selectable &&
66490          activeObject &&
66491          activeObject !== target)
66492      );
66493    },
66494
66495    /**
66496     * centeredScaling from object can't override centeredScaling from canvas.
66497     * this should be fixed, since object setting should take precedence over canvas.
66498     * also this should be something that will be migrated in the control properties.
66499     * as ability to define the origin of the transformation that the control provide.
66500     * @private
66501     * @param {fabric.Object} target
66502     * @param {String} action
66503     * @param {Boolean} altKey
66504     */
66505    _shouldCenterTransform: function (target, action, altKey) {
66506      if (!target) {
66507        return;
66508      }
66509
66510      var centerTransform;
66511
66512      if (action === 'scale' || action === 'scaleX' || action === 'scaleY' || action === 'resizing') {
66513        centerTransform = this.centeredScaling || target.centeredScaling;
66514      }
66515      else if (action === 'rotate') {
66516        centerTransform = this.centeredRotation || target.centeredRotation;
66517      }
66518
66519      return centerTransform ? !altKey : altKey;
66520    },
66521
66522    /**
66523     * should disappear before release 4.0
66524     * @private
66525     */
66526    _getOriginFromCorner: function(target, corner) {
66527      var origin = {
66528        x: target.originX,
66529        y: target.originY
66530      };
66531
66532      if (corner === 'ml' || corner === 'tl' || corner === 'bl') {
66533        origin.x = 'right';
66534      }
66535      else if (corner === 'mr' || corner === 'tr' || corner === 'br') {
66536        origin.x = 'left';
66537      }
66538
66539      if (corner === 'tl' || corner === 'mt' || corner === 'tr') {
66540        origin.y = 'bottom';
66541      }
66542      else if (corner === 'bl' || corner === 'mb' || corner === 'br') {
66543        origin.y = 'top';
66544      }
66545      return origin;
66546    },
66547
66548    /**
66549     * @private
66550     * @param {Boolean} alreadySelected true if target is already selected
66551     * @param {String} corner a string representing the corner ml, mr, tl ...
66552     * @param {Event} e Event object
66553     * @param {fabric.Object} [target] inserted back to help overriding. Unused
66554     */
66555    _getActionFromCorner: function(alreadySelected, corner, e, target) {
66556      if (!corner || !alreadySelected) {
66557        return 'drag';
66558      }
66559      var control = target.controls[corner];
66560      return control.getActionName(e, control, target);
66561    },
66562
66563    /**
66564     * @private
66565     * @param {Event} e Event object
66566     * @param {fabric.Object} target
66567     */
66568    _setupCurrentTransform: function (e, target, alreadySelected) {
66569      if (!target) {
66570        return;
66571      }
66572
66573      var pointer = this.getPointer(e), corner = target.__corner,
66574          control = target.controls[corner],
66575          actionHandler = (alreadySelected && corner) ?
66576            control.getActionHandler(e, target, control) : fabric.controlsUtils.dragHandler,
66577          action = this._getActionFromCorner(alreadySelected, corner, e, target),
66578          origin = this._getOriginFromCorner(target, corner),
66579          altKey = e[this.centeredKey],
66580          transform = {
66581            target: target,
66582            action: action,
66583            actionHandler: actionHandler,
66584            corner: corner,
66585            scaleX: target.scaleX,
66586            scaleY: target.scaleY,
66587            skewX: target.skewX,
66588            skewY: target.skewY,
66589            // used by transation
66590            offsetX: pointer.x - target.left,
66591            offsetY: pointer.y - target.top,
66592            originX: origin.x,
66593            originY: origin.y,
66594            ex: pointer.x,
66595            ey: pointer.y,
66596            lastX: pointer.x,
66597            lastY: pointer.y,
66598            // unsure they are useful anymore.
66599            // left: target.left,
66600            // top: target.top,
66601            theta: degreesToRadians(target.angle),
66602            // end of unsure
66603            width: target.width * target.scaleX,
66604            shiftKey: e.shiftKey,
66605            altKey: altKey,
66606            original: fabric.util.saveObjectTransform(target),
66607          };
66608
66609      if (this._shouldCenterTransform(target, action, altKey)) {
66610        transform.originX = 'center';
66611        transform.originY = 'center';
66612      }
66613      transform.original.originX = origin.x;
66614      transform.original.originY = origin.y;
66615      this._currentTransform = transform;
66616      this._beforeTransform(e);
66617    },
66618
66619    /**
66620     * Set the cursor type of the canvas element
66621     * @param {String} value Cursor type of the canvas element.
66622     * @see http://www.w3.org/TR/css3-ui/#cursor
66623     */
66624    setCursor: function (value) {
66625      this.upperCanvasEl.style.cursor = value;
66626    },
66627
66628    /**
66629     * @private
66630     * @param {CanvasRenderingContext2D} ctx to draw the selection on
66631     */
66632    _drawSelection: function (ctx) {
66633      var selector = this._groupSelector,
66634          viewportStart = new fabric.Point(selector.ex, selector.ey),
66635          start = fabric.util.transformPoint(viewportStart, this.viewportTransform),
66636          viewportExtent = new fabric.Point(selector.ex + selector.left, selector.ey + selector.top),
66637          extent = fabric.util.transformPoint(viewportExtent, this.viewportTransform),
66638          minX = Math.min(start.x, extent.x),
66639          minY = Math.min(start.y, extent.y),
66640          maxX = Math.max(start.x, extent.x),
66641          maxY = Math.max(start.y, extent.y),
66642          strokeOffset = this.selectionLineWidth / 2;
66643
66644      if (this.selectionColor) {
66645        ctx.fillStyle = this.selectionColor;
66646        ctx.fillRect(minX, minY, maxX - minX, maxY - minY);
66647      }
66648
66649      if (!this.selectionLineWidth || !this.selectionBorderColor) {
66650        return;
66651      }
66652      ctx.lineWidth = this.selectionLineWidth;
66653      ctx.strokeStyle = this.selectionBorderColor;
66654
66655      minX += strokeOffset;
66656      minY += strokeOffset;
66657      maxX -= strokeOffset;
66658      maxY -= strokeOffset;
66659      // selection border
66660      fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray);
66661      ctx.strokeRect(minX, minY, maxX - minX, maxY - minY);
66662    },
66663
66664    /**
66665     * Method that determines what object we are clicking on
66666     * the skipGroup parameter is for internal use, is needed for shift+click action
66667     * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target
66668     * or the outside part of the corner.
66669     * @param {Event} e mouse event
66670     * @param {Boolean} skipGroup when true, activeGroup is skipped and only objects are traversed through
66671     * @return {fabric.Object} the target found
66672     */
66673    findTarget: function (e, skipGroup) {
66674      if (this.skipTargetFind) {
66675        return;
66676      }
66677
66678      var ignoreZoom = true,
66679          pointer = this.getPointer(e, ignoreZoom),
66680          activeObject = this._activeObject,
66681          aObjects = this.getActiveObjects(),
66682          activeTarget, activeTargetSubs,
66683          isTouch = isTouchEvent(e),
66684          shouldLookForActive = (aObjects.length > 1 && !skipGroup) || aObjects.length === 1;
66685
66686      // first check current group (if one exists)
66687      // active group does not check sub targets like normal groups.
66688      // if active group just exits.
66689      this.targets = [];
66690
66691      // if we hit the corner of an activeObject, let's return that.
66692      if (shouldLookForActive && activeObject._findTargetCorner(pointer, isTouch)) {
66693        return activeObject;
66694      }
66695      if (aObjects.length > 1 && !skipGroup && activeObject === this._searchPossibleTargets([activeObject], pointer)) {
66696        return activeObject;
66697      }
66698      if (aObjects.length === 1 &&
66699        activeObject === this._searchPossibleTargets([activeObject], pointer)) {
66700        if (!this.preserveObjectStacking) {
66701          return activeObject;
66702        }
66703        else {
66704          activeTarget = activeObject;
66705          activeTargetSubs = this.targets;
66706          this.targets = [];
66707        }
66708      }
66709      var target = this._searchPossibleTargets(this._objects, pointer);
66710      if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) {
66711        target = activeTarget;
66712        this.targets = activeTargetSubs;
66713      }
66714      return target;
66715    },
66716
66717    /**
66718     * Checks point is inside the object.
66719     * @param {Object} [pointer] x,y object of point coordinates we want to check.
66720     * @param {fabric.Object} obj Object to test against
66721     * @param {Object} [globalPointer] x,y object of point coordinates relative to canvas used to search per pixel target.
66722     * @return {Boolean} true if point is contained within an area of given object
66723     * @private
66724     */
66725    _checkTarget: function(pointer, obj, globalPointer) {
66726      if (obj &&
66727          obj.visible &&
66728          obj.evented &&
66729          // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html
66730          // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html
66731          obj.containsPoint(pointer)
66732      ) {
66733        if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) {
66734          var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y);
66735          if (!isTransparent) {
66736            return true;
66737          }
66738        }
66739        else {
66740          return true;
66741        }
66742      }
66743    },
66744
66745    /**
66746     * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted
66747     * @param {Array} [objects] objects array to look into
66748     * @param {Object} [pointer] x,y object of point coordinates we want to check.
66749     * @return {fabric.Object} object that contains pointer
66750     * @private
66751     */
66752    _searchPossibleTargets: function(objects, pointer) {
66753      // Cache all targets where their bounding box contains point.
66754      var target, i = objects.length, subTarget;
66755      // Do not check for currently grouped objects, since we check the parent group itself.
66756      // until we call this function specifically to search inside the activeGroup
66757      while (i--) {
66758        var objToCheck = objects[i];
66759        var pointerToUse = objToCheck.group ?
66760          this._normalizePointer(objToCheck.group, pointer) : pointer;
66761        if (this._checkTarget(pointerToUse, objToCheck, pointer)) {
66762          target = objects[i];
66763          if (target.subTargetCheck && target instanceof fabric.Group) {
66764            subTarget = this._searchPossibleTargets(target._objects, pointer);
66765            subTarget && this.targets.push(subTarget);
66766          }
66767          break;
66768        }
66769      }
66770      return target;
66771    },
66772
66773    /**
66774     * Returns pointer coordinates without the effect of the viewport
66775     * @param {Object} pointer with "x" and "y" number values
66776     * @return {Object} object with "x" and "y" number values
66777     */
66778    restorePointerVpt: function(pointer) {
66779      return fabric.util.transformPoint(
66780        pointer,
66781        fabric.util.invertTransform(this.viewportTransform)
66782      );
66783    },
66784
66785    /**
66786     * Returns pointer coordinates relative to canvas.
66787     * Can return coordinates with or without viewportTransform.
66788     * ignoreZoom false gives back coordinates that represent
66789     * the point clicked on canvas element.
66790     * ignoreZoom true gives back coordinates after being processed
66791     * by the viewportTransform ( sort of coordinates of what is displayed
66792     * on the canvas where you are clicking.
66793     * ignoreZoom true = HTMLElement coordinates relative to top,left
66794     * ignoreZoom false, default = fabric space coordinates, the same used for shape position
66795     * To interact with your shapes top and left you want to use ignoreZoom true
66796     * most of the time, while ignoreZoom false will give you coordinates
66797     * compatible with the object.oCoords system.
66798     * of the time.
66799     * @param {Event} e
66800     * @param {Boolean} ignoreZoom
66801     * @return {Object} object with "x" and "y" number values
66802     */
66803    getPointer: function (e, ignoreZoom) {
66804      // return cached values if we are in the event processing chain
66805      if (this._absolutePointer && !ignoreZoom) {
66806        return this._absolutePointer;
66807      }
66808      if (this._pointer && ignoreZoom) {
66809        return this._pointer;
66810      }
66811
66812      var pointer = getPointer(e),
66813          upperCanvasEl = this.upperCanvasEl,
66814          bounds = upperCanvasEl.getBoundingClientRect(),
66815          boundsWidth = bounds.width || 0,
66816          boundsHeight = bounds.height || 0,
66817          cssScale;
66818
66819      if (!boundsWidth || !boundsHeight ) {
66820        if ('top' in bounds && 'bottom' in bounds) {
66821          boundsHeight = Math.abs( bounds.top - bounds.bottom );
66822        }
66823        if ('right' in bounds && 'left' in bounds) {
66824          boundsWidth = Math.abs( bounds.right - bounds.left );
66825        }
66826      }
66827
66828      this.calcOffset();
66829      pointer.x = pointer.x - this._offset.left;
66830      pointer.y = pointer.y - this._offset.top;
66831      if (!ignoreZoom) {
66832        pointer = this.restorePointerVpt(pointer);
66833      }
66834
66835      var retinaScaling = this.getRetinaScaling();
66836      if (retinaScaling !== 1) {
66837        pointer.x /= retinaScaling;
66838        pointer.y /= retinaScaling;
66839      }
66840
66841      if (boundsWidth === 0 || boundsHeight === 0) {
66842        // If bounds are not available (i.e. not visible), do not apply scale.
66843        cssScale = { width: 1, height: 1 };
66844      }
66845      else {
66846        cssScale = {
66847          width: upperCanvasEl.width / boundsWidth,
66848          height: upperCanvasEl.height / boundsHeight
66849        };
66850      }
66851
66852      return {
66853        x: pointer.x * cssScale.width,
66854        y: pointer.y * cssScale.height
66855      };
66856    },
66857
66858    /**
66859     * @private
66860     * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized
66861     */
66862    _createUpperCanvas: function () {
66863      var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, ''),
66864          lowerCanvasEl = this.lowerCanvasEl, upperCanvasEl = this.upperCanvasEl;
66865
66866      // there is no need to create a new upperCanvas element if we have already one.
66867      if (upperCanvasEl) {
66868        upperCanvasEl.className = '';
66869      }
66870      else {
66871        upperCanvasEl = this._createCanvasElement();
66872        this.upperCanvasEl = upperCanvasEl;
66873      }
66874      fabric.util.addClass(upperCanvasEl, 'upper-canvas ' + lowerCanvasClass);
66875
66876      this.wrapperEl.appendChild(upperCanvasEl);
66877
66878      this._copyCanvasStyle(lowerCanvasEl, upperCanvasEl);
66879      this._applyCanvasStyle(upperCanvasEl);
66880      this.contextTop = upperCanvasEl.getContext('2d');
66881    },
66882
66883    /**
66884     * @private
66885     */
66886    _createCacheCanvas: function () {
66887      this.cacheCanvasEl = this._createCanvasElement();
66888      this.cacheCanvasEl.setAttribute('width', this.width);
66889      this.cacheCanvasEl.setAttribute('height', this.height);
66890      this.contextCache = this.cacheCanvasEl.getContext('2d');
66891    },
66892
66893    /**
66894     * @private
66895     */
66896    _initWrapperElement: function () {
66897      this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', {
66898        'class': this.containerClass
66899      });
66900      fabric.util.setStyle(this.wrapperEl, {
66901        width: this.width + 'px',
66902        height: this.height + 'px',
66903        position: 'relative'
66904      });
66905      fabric.util.makeElementUnselectable(this.wrapperEl);
66906    },
66907
66908    /**
66909     * @private
66910     * @param {HTMLElement} element canvas element to apply styles on
66911     */
66912    _applyCanvasStyle: function (element) {
66913      var width = this.width || element.width,
66914          height = this.height || element.height;
66915
66916      fabric.util.setStyle(element, {
66917        position: 'absolute',
66918        width: width + 'px',
66919        height: height + 'px',
66920        left: 0,
66921        top: 0,
66922        'touch-action': this.allowTouchScrolling ? 'manipulation' : 'none',
66923        '-ms-touch-action': this.allowTouchScrolling ? 'manipulation' : 'none'
66924      });
66925      element.width = width;
66926      element.height = height;
66927      fabric.util.makeElementUnselectable(element);
66928    },
66929
66930    /**
66931     * Copy the entire inline style from one element (fromEl) to another (toEl)
66932     * @private
66933     * @param {Element} fromEl Element style is copied from
66934     * @param {Element} toEl Element copied style is applied to
66935     */
66936    _copyCanvasStyle: function (fromEl, toEl) {
66937      toEl.style.cssText = fromEl.style.cssText;
66938    },
66939
66940    /**
66941     * Returns context of canvas where object selection is drawn
66942     * @return {CanvasRenderingContext2D}
66943     */
66944    getSelectionContext: function() {
66945      return this.contextTop;
66946    },
66947
66948    /**
66949     * Returns &lt;canvas> element on which object selection is drawn
66950     * @return {HTMLCanvasElement}
66951     */
66952    getSelectionElement: function () {
66953      return this.upperCanvasEl;
66954    },
66955
66956    /**
66957     * Returns currently active object
66958     * @return {fabric.Object} active object
66959     */
66960    getActiveObject: function () {
66961      return this._activeObject;
66962    },
66963
66964    /**
66965     * Returns an array with the current selected objects
66966     * @return {fabric.Object} active object
66967     */
66968    getActiveObjects: function () {
66969      var active = this._activeObject;
66970      if (active) {
66971        if (active.type === 'activeSelection' && active._objects) {
66972          return active._objects.slice(0);
66973        }
66974        else {
66975          return [active];
66976        }
66977      }
66978      return [];
66979    },
66980
66981    /**
66982     * @private
66983     * @param {fabric.Object} obj Object that was removed
66984     */
66985    _onObjectRemoved: function(obj) {
66986      // removing active object should fire "selection:cleared" events
66987      if (obj === this._activeObject) {
66988        this.fire('before:selection:cleared', { target: obj });
66989        this._discardActiveObject();
66990        this.fire('selection:cleared', { target: obj });
66991        obj.fire('deselected');
66992      }
66993      if (obj === this._hoveredTarget){
66994        this._hoveredTarget = null;
66995        this._hoveredTargets = [];
66996      }
66997      this.callSuper('_onObjectRemoved', obj);
66998    },
66999
67000    /**
67001     * @private
67002     * Compares the old activeObject with the current one and fires correct events
67003     * @param {fabric.Object} obj old activeObject
67004     */
67005    _fireSelectionEvents: function(oldObjects, e) {
67006      var somethingChanged = false, objects = this.getActiveObjects(),
67007          added = [], removed = [];
67008      oldObjects.forEach(function(oldObject) {
67009        if (objects.indexOf(oldObject) === -1) {
67010          somethingChanged = true;
67011          oldObject.fire('deselected', {
67012            e: e,
67013            target: oldObject
67014          });
67015          removed.push(oldObject);
67016        }
67017      });
67018      objects.forEach(function(object) {
67019        if (oldObjects.indexOf(object) === -1) {
67020          somethingChanged = true;
67021          object.fire('selected', {
67022            e: e,
67023            target: object
67024          });
67025          added.push(object);
67026        }
67027      });
67028      if (oldObjects.length > 0 && objects.length > 0) {
67029        somethingChanged && this.fire('selection:updated', {
67030          e: e,
67031          selected: added,
67032          deselected: removed,
67033          // added for backward compatibility
67034          // deprecated
67035          updated: added[0] || removed[0],
67036          target: this._activeObject,
67037        });
67038      }
67039      else if (objects.length > 0) {
67040        this.fire('selection:created', {
67041          e: e,
67042          selected: added,
67043          target: this._activeObject,
67044        });
67045      }
67046      else if (oldObjects.length > 0) {
67047        this.fire('selection:cleared', {
67048          e: e,
67049          deselected: removed,
67050        });
67051      }
67052    },
67053
67054    /**
67055     * Sets given object as the only active object on canvas
67056     * @param {fabric.Object} object Object to set as an active one
67057     * @param {Event} [e] Event (passed along when firing "object:selected")
67058     * @return {fabric.Canvas} thisArg
67059     * @chainable
67060     */
67061    setActiveObject: function (object, e) {
67062      var currentActives = this.getActiveObjects();
67063      this._setActiveObject(object, e);
67064      this._fireSelectionEvents(currentActives, e);
67065      return this;
67066    },
67067
67068    /**
67069     * This is a private method for now.
67070     * This is supposed to be equivalent to setActiveObject but without firing
67071     * any event. There is commitment to have this stay this way.
67072     * This is the functional part of setActiveObject.
67073     * @private
67074     * @param {Object} object to set as active
67075     * @param {Event} [e] Event (passed along when firing "object:selected")
67076     * @return {Boolean} true if the selection happened
67077     */
67078    _setActiveObject: function(object, e) {
67079      if (this._activeObject === object) {
67080        return false;
67081      }
67082      if (!this._discardActiveObject(e, object)) {
67083        return false;
67084      }
67085      if (object.onSelect({ e: e })) {
67086        return false;
67087      }
67088      this._activeObject = object;
67089      return true;
67090    },
67091
67092    /**
67093     * This is a private method for now.
67094     * This is supposed to be equivalent to discardActiveObject but without firing
67095     * any events. There is commitment to have this stay this way.
67096     * This is the functional part of discardActiveObject.
67097     * @param {Event} [e] Event (passed along when firing "object:deselected")
67098     * @param {Object} object to set as active
67099     * @return {Boolean} true if the selection happened
67100     * @private
67101     */
67102    _discardActiveObject: function(e, object) {
67103      var obj = this._activeObject;
67104      if (obj) {
67105        // onDeselect return TRUE to cancel selection;
67106        if (obj.onDeselect({ e: e, object: object })) {
67107          return false;
67108        }
67109        this._activeObject = null;
67110      }
67111      return true;
67112    },
67113
67114    /**
67115     * Discards currently active object and fire events. If the function is called by fabric
67116     * as a consequence of a mouse event, the event is passed as a parameter and
67117     * sent to the fire function for the custom events. When used as a method the
67118     * e param does not have any application.
67119     * @param {event} e
67120     * @return {fabric.Canvas} thisArg
67121     * @chainable
67122     */
67123    discardActiveObject: function (e) {
67124      var currentActives = this.getActiveObjects(), activeObject = this.getActiveObject();
67125      if (currentActives.length) {
67126        this.fire('before:selection:cleared', { target: activeObject, e: e });
67127      }
67128      this._discardActiveObject(e);
67129      this._fireSelectionEvents(currentActives, e);
67130      return this;
67131    },
67132
67133    /**
67134     * Clears a canvas element and removes all event listeners
67135     * @return {fabric.Canvas} thisArg
67136     * @chainable
67137     */
67138    dispose: function () {
67139      var wrapper = this.wrapperEl;
67140      this.removeListeners();
67141      wrapper.removeChild(this.upperCanvasEl);
67142      wrapper.removeChild(this.lowerCanvasEl);
67143      this.contextCache = null;
67144      this.contextTop = null;
67145      ['upperCanvasEl', 'cacheCanvasEl'].forEach((function(element) {
67146        fabric.util.cleanUpJsdomNode(this[element]);
67147        this[element] = undefined;
67148      }).bind(this));
67149      if (wrapper.parentNode) {
67150        wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl);
67151      }
67152      delete this.wrapperEl;
67153      fabric.StaticCanvas.prototype.dispose.call(this);
67154      return this;
67155    },
67156
67157    /**
67158     * Clears all contexts (background, main, top) of an instance
67159     * @return {fabric.Canvas} thisArg
67160     * @chainable
67161     */
67162    clear: function () {
67163      // this.discardActiveGroup();
67164      this.discardActiveObject();
67165      this.clearContext(this.contextTop);
67166      return this.callSuper('clear');
67167    },
67168
67169    /**
67170     * Draws objects' controls (borders/controls)
67171     * @param {CanvasRenderingContext2D} ctx Context to render controls on
67172     */
67173    drawControls: function(ctx) {
67174      var activeObject = this._activeObject;
67175
67176      if (activeObject) {
67177        activeObject._renderControls(ctx);
67178      }
67179    },
67180
67181    /**
67182     * @private
67183     */
67184    _toObject: function(instance, methodName, propertiesToInclude) {
67185      //If the object is part of the current selection group, it should
67186      //be transformed appropriately
67187      //i.e. it should be serialised as it would appear if the selection group
67188      //were to be destroyed.
67189      var originalProperties = this._realizeGroupTransformOnObject(instance),
67190          object = this.callSuper('_toObject', instance, methodName, propertiesToInclude);
67191      //Undo the damage we did by changing all of its properties
67192      this._unwindGroupTransformOnObject(instance, originalProperties);
67193      return object;
67194    },
67195
67196    /**
67197     * Realises an object's group transformation on it
67198     * @private
67199     * @param {fabric.Object} [instance] the object to transform (gets mutated)
67200     * @returns the original values of instance which were changed
67201     */
67202    _realizeGroupTransformOnObject: function(instance) {
67203      if (instance.group && instance.group.type === 'activeSelection' && this._activeObject === instance.group) {
67204        var layoutProps = ['angle', 'flipX', 'flipY', 'left', 'scaleX', 'scaleY', 'skewX', 'skewY', 'top'];
67205        //Copy all the positionally relevant properties across now
67206        var originalValues = {};
67207        layoutProps.forEach(function(prop) {
67208          originalValues[prop] = instance[prop];
67209        });
67210        fabric.util.addTransformToObject(instance, this._activeObject.calcOwnMatrix());
67211        return originalValues;
67212      }
67213      else {
67214        return null;
67215      }
67216    },
67217
67218    /**
67219     * Restores the changed properties of instance
67220     * @private
67221     * @param {fabric.Object} [instance] the object to un-transform (gets mutated)
67222     * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject
67223     */
67224    _unwindGroupTransformOnObject: function(instance, originalValues) {
67225      if (originalValues) {
67226        instance.set(originalValues);
67227      }
67228    },
67229
67230    /**
67231     * @private
67232     */
67233    _setSVGObject: function(markup, instance, reviver) {
67234      //If the object is in a selection group, simulate what would happen to that
67235      //object when the group is deselected
67236      var originalProperties = this._realizeGroupTransformOnObject(instance);
67237      this.callSuper('_setSVGObject', markup, instance, reviver);
67238      this._unwindGroupTransformOnObject(instance, originalProperties);
67239    },
67240
67241    setViewportTransform: function (vpt) {
67242      if (this.renderOnAddRemove && this._activeObject && this._activeObject.isEditing) {
67243        this._activeObject.clearContextTop();
67244      }
67245      fabric.StaticCanvas.prototype.setViewportTransform.call(this, vpt);
67246    }
67247  });
67248
67249  // copying static properties manually to work around Opera's bug,
67250  // where "prototype" property is enumerable and overrides existing prototype
67251  for (var prop in fabric.StaticCanvas) {
67252    if (prop !== 'prototype') {
67253      fabric.Canvas[prop] = fabric.StaticCanvas[prop];
67254    }
67255  }
67256})();
67257
67258
67259(function() {
67260
67261  var addListener = fabric.util.addListener,
67262      removeListener = fabric.util.removeListener,
67263      RIGHT_CLICK = 3, MIDDLE_CLICK = 2, LEFT_CLICK = 1,
67264      addEventOptions = { passive: false };
67265
67266  function checkClick(e, value) {
67267    return e.button && (e.button === value - 1);
67268  }
67269
67270  fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {
67271
67272    /**
67273     * Contains the id of the touch event that owns the fabric transform
67274     * @type Number
67275     * @private
67276     */
67277    mainTouchId: null,
67278
67279    /**
67280     * Adds mouse listeners to canvas
67281     * @private
67282     */
67283    _initEventListeners: function () {
67284      // in case we initialized the class twice. This should not happen normally
67285      // but in some kind of applications where the canvas element may be changed
67286      // this is a workaround to having double listeners.
67287      this.removeListeners();
67288      this._bindEvents();
67289      this.addOrRemove(addListener, 'add');
67290    },
67291
67292    /**
67293     * return an event prefix pointer or mouse.
67294     * @private
67295     */
67296    _getEventPrefix: function () {
67297      return this.enablePointerEvents ? 'pointer' : 'mouse';
67298    },
67299
67300    addOrRemove: function(functor, eventjsFunctor) {
67301      var canvasElement = this.upperCanvasEl,
67302          eventTypePrefix = this._getEventPrefix();
67303      functor(fabric.window, 'resize', this._onResize);
67304      functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown);
67305      functor(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);
67306      functor(canvasElement, eventTypePrefix + 'out', this._onMouseOut);
67307      functor(canvasElement, eventTypePrefix + 'enter', this._onMouseEnter);
67308      functor(canvasElement, 'wheel', this._onMouseWheel);
67309      functor(canvasElement, 'contextmenu', this._onContextMenu);
67310      functor(canvasElement, 'dblclick', this._onDoubleClick);
67311      functor(canvasElement, 'dragover', this._onDragOver);
67312      functor(canvasElement, 'dragenter', this._onDragEnter);
67313      functor(canvasElement, 'dragleave', this._onDragLeave);
67314      functor(canvasElement, 'drop', this._onDrop);
67315      if (!this.enablePointerEvents) {
67316        functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions);
67317      }
67318      if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) {
67319        eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture);
67320        eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag);
67321        eventjs[eventjsFunctor](canvasElement, 'orientation', this._onOrientationChange);
67322        eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake);
67323        eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress);
67324      }
67325    },
67326
67327    /**
67328     * Removes all event listeners
67329     */
67330    removeListeners: function() {
67331      this.addOrRemove(removeListener, 'remove');
67332      // if you dispose on a mouseDown, before mouse up, you need to clean document to...
67333      var eventTypePrefix = this._getEventPrefix();
67334      removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);
67335      removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);
67336      removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);
67337      removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);
67338    },
67339
67340    /**
67341     * @private
67342     */
67343    _bindEvents: function() {
67344      if (this.eventsBound) {
67345        // for any reason we pass here twice we do not want to bind events twice.
67346        return;
67347      }
67348      this._onMouseDown = this._onMouseDown.bind(this);
67349      this._onTouchStart = this._onTouchStart.bind(this);
67350      this._onMouseMove = this._onMouseMove.bind(this);
67351      this._onMouseUp = this._onMouseUp.bind(this);
67352      this._onTouchEnd = this._onTouchEnd.bind(this);
67353      this._onResize = this._onResize.bind(this);
67354      this._onGesture = this._onGesture.bind(this);
67355      this._onDrag = this._onDrag.bind(this);
67356      this._onShake = this._onShake.bind(this);
67357      this._onLongPress = this._onLongPress.bind(this);
67358      this._onOrientationChange = this._onOrientationChange.bind(this);
67359      this._onMouseWheel = this._onMouseWheel.bind(this);
67360      this._onMouseOut = this._onMouseOut.bind(this);
67361      this._onMouseEnter = this._onMouseEnter.bind(this);
67362      this._onContextMenu = this._onContextMenu.bind(this);
67363      this._onDoubleClick = this._onDoubleClick.bind(this);
67364      this._onDragOver = this._onDragOver.bind(this);
67365      this._onDragEnter = this._simpleEventHandler.bind(this, 'dragenter');
67366      this._onDragLeave = this._simpleEventHandler.bind(this, 'dragleave');
67367      this._onDrop = this._simpleEventHandler.bind(this, 'drop');
67368      this.eventsBound = true;
67369    },
67370
67371    /**
67372     * @private
67373     * @param {Event} [e] Event object fired on Event.js gesture
67374     * @param {Event} [self] Inner Event object
67375     */
67376    _onGesture: function(e, self) {
67377      this.__onTransformGesture && this.__onTransformGesture(e, self);
67378    },
67379
67380    /**
67381     * @private
67382     * @param {Event} [e] Event object fired on Event.js drag
67383     * @param {Event} [self] Inner Event object
67384     */
67385    _onDrag: function(e, self) {
67386      this.__onDrag && this.__onDrag(e, self);
67387    },
67388
67389    /**
67390     * @private
67391     * @param {Event} [e] Event object fired on wheel event
67392     */
67393    _onMouseWheel: function(e) {
67394      this.__onMouseWheel(e);
67395    },
67396
67397    /**
67398     * @private
67399     * @param {Event} e Event object fired on mousedown
67400     */
67401    _onMouseOut: function(e) {
67402      var target = this._hoveredTarget;
67403      this.fire('mouse:out', { target: target, e: e });
67404      this._hoveredTarget = null;
67405      target && target.fire('mouseout', { e: e });
67406
67407      var _this = this;
67408      this._hoveredTargets.forEach(function(_target){
67409        _this.fire('mouse:out', { target: target, e: e });
67410        _target && target.fire('mouseout', { e: e });
67411      });
67412      this._hoveredTargets = [];
67413
67414      if (this._iTextInstances) {
67415        this._iTextInstances.forEach(function(obj) {
67416          if (obj.isEditing) {
67417            obj.hiddenTextarea.focus();
67418          }
67419        });
67420      }
67421    },
67422
67423    /**
67424     * @private
67425     * @param {Event} e Event object fired on mouseenter
67426     */
67427    _onMouseEnter: function(e) {
67428      // This find target and consequent 'mouse:over' is used to
67429      // clear old instances on hovered target.
67430      // calling findTarget has the side effect of killing target.__corner.
67431      // as a short term fix we are not firing this if we are currently transforming.
67432      // as a long term fix we need to separate the action of finding a target with the
67433      // side effects we added to it.
67434      if (!this._currentTransform && !this.findTarget(e)) {
67435        this.fire('mouse:over', { target: null, e: e });
67436        this._hoveredTarget = null;
67437        this._hoveredTargets = [];
67438      }
67439    },
67440
67441    /**
67442     * @private
67443     * @param {Event} [e] Event object fired on Event.js orientation change
67444     * @param {Event} [self] Inner Event object
67445     */
67446    _onOrientationChange: function(e, self) {
67447      this.__onOrientationChange && this.__onOrientationChange(e, self);
67448    },
67449
67450    /**
67451     * @private
67452     * @param {Event} [e] Event object fired on Event.js shake
67453     * @param {Event} [self] Inner Event object
67454     */
67455    _onShake: function(e, self) {
67456      this.__onShake && this.__onShake(e, self);
67457    },
67458
67459    /**
67460     * @private
67461     * @param {Event} [e] Event object fired on Event.js shake
67462     * @param {Event} [self] Inner Event object
67463     */
67464    _onLongPress: function(e, self) {
67465      this.__onLongPress && this.__onLongPress(e, self);
67466    },
67467
67468    /**
67469     * prevent default to allow drop event to be fired
67470     * @private
67471     * @param {Event} [e] Event object fired on Event.js shake
67472     */
67473    _onDragOver: function(e) {
67474      e.preventDefault();
67475      var target = this._simpleEventHandler('dragover', e);
67476      this._fireEnterLeaveEvents(target, e);
67477    },
67478
67479    /**
67480     * @private
67481     * @param {Event} e Event object fired on mousedown
67482     */
67483    _onContextMenu: function (e) {
67484      if (this.stopContextMenu) {
67485        e.stopPropagation();
67486        e.preventDefault();
67487      }
67488      return false;
67489    },
67490
67491    /**
67492     * @private
67493     * @param {Event} e Event object fired on mousedown
67494     */
67495    _onDoubleClick: function (e) {
67496      this._cacheTransformEventData(e);
67497      this._handleEvent(e, 'dblclick');
67498      this._resetTransformEventData(e);
67499    },
67500
67501    /**
67502     * Return a the id of an event.
67503     * returns either the pointerId or the identifier or 0 for the mouse event
67504     * @private
67505     * @param {Event} evt Event object
67506     */
67507    getPointerId: function(evt) {
67508      var changedTouches = evt.changedTouches;
67509
67510      if (changedTouches) {
67511        return changedTouches[0] && changedTouches[0].identifier;
67512      }
67513
67514      if (this.enablePointerEvents) {
67515        return evt.pointerId;
67516      }
67517
67518      return -1;
67519    },
67520
67521    /**
67522     * Determines if an event has the id of the event that is considered main
67523     * @private
67524     * @param {evt} event Event object
67525     */
67526    _isMainEvent: function(evt) {
67527      if (evt.isPrimary === true) {
67528        return true;
67529      }
67530      if (evt.isPrimary === false) {
67531        return false;
67532      }
67533      if (evt.type === 'touchend' && evt.touches.length === 0) {
67534        return true;
67535      }
67536      if (evt.changedTouches) {
67537        return evt.changedTouches[0].identifier === this.mainTouchId;
67538      }
67539      return true;
67540    },
67541
67542    /**
67543     * @private
67544     * @param {Event} e Event object fired on mousedown
67545     */
67546    _onTouchStart: function(e) {
67547      e.preventDefault();
67548      if (this.mainTouchId === null) {
67549        this.mainTouchId = this.getPointerId(e);
67550      }
67551      this.__onMouseDown(e);
67552      this._resetTransformEventData();
67553      var canvasElement = this.upperCanvasEl,
67554          eventTypePrefix = this._getEventPrefix();
67555      addListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);
67556      addListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);
67557      // Unbind mousedown to prevent double triggers from touch devices
67558      removeListener(canvasElement, eventTypePrefix + 'down', this._onMouseDown);
67559    },
67560
67561    /**
67562     * @private
67563     * @param {Event} e Event object fired on mousedown
67564     */
67565    _onMouseDown: function (e) {
67566      this.__onMouseDown(e);
67567      this._resetTransformEventData();
67568      var canvasElement = this.upperCanvasEl,
67569          eventTypePrefix = this._getEventPrefix();
67570      removeListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);
67571      addListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);
67572      addListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);
67573    },
67574
67575    /**
67576     * @private
67577     * @param {Event} e Event object fired on mousedown
67578     */
67579    _onTouchEnd: function(e) {
67580      if (e.touches.length > 0) {
67581        // if there are still touches stop here
67582        return;
67583      }
67584      this.__onMouseUp(e);
67585      this._resetTransformEventData();
67586      this.mainTouchId = null;
67587      var eventTypePrefix = this._getEventPrefix();
67588      removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);
67589      removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);
67590      var _this = this;
67591      if (this._willAddMouseDown) {
67592        clearTimeout(this._willAddMouseDown);
67593      }
67594      this._willAddMouseDown = setTimeout(function() {
67595        // Wait 400ms before rebinding mousedown to prevent double triggers
67596        // from touch devices
67597        addListener(_this.upperCanvasEl, eventTypePrefix + 'down', _this._onMouseDown);
67598        _this._willAddMouseDown = 0;
67599      }, 400);
67600    },
67601
67602    /**
67603     * @private
67604     * @param {Event} e Event object fired on mouseup
67605     */
67606    _onMouseUp: function (e) {
67607      this.__onMouseUp(e);
67608      this._resetTransformEventData();
67609      var canvasElement = this.upperCanvasEl,
67610          eventTypePrefix = this._getEventPrefix();
67611      if (this._isMainEvent(e)) {
67612        removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);
67613        removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);
67614        addListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);
67615      }
67616    },
67617
67618    /**
67619     * @private
67620     * @param {Event} e Event object fired on mousemove
67621     */
67622    _onMouseMove: function (e) {
67623      !this.allowTouchScrolling && e.preventDefault && e.preventDefault();
67624      this.__onMouseMove(e);
67625    },
67626
67627    /**
67628     * @private
67629     */
67630    _onResize: function () {
67631      this.calcOffset();
67632    },
67633
67634    /**
67635     * Decides whether the canvas should be redrawn in mouseup and mousedown events.
67636     * @private
67637     * @param {Object} target
67638     */
67639    _shouldRender: function(target) {
67640      var activeObject = this._activeObject;
67641
67642      if (
67643        !!activeObject !== !!target ||
67644        (activeObject && target && (activeObject !== target))
67645      ) {
67646        // this covers: switch of target, from target to no target, selection of target
67647        // multiSelection with key and mouse
67648        return true;
67649      }
67650      else if (activeObject && activeObject.isEditing) {
67651        // if we mouse up/down over a editing textbox a cursor change,
67652        // there is no need to re render
67653        return false;
67654      }
67655      return false;
67656    },
67657
67658    /**
67659     * Method that defines the actions when mouse is released on canvas.
67660     * The method resets the currentTransform parameters, store the image corner
67661     * position in the image object and render the canvas on top.
67662     * @private
67663     * @param {Event} e Event object fired on mouseup
67664     */
67665    __onMouseUp: function (e) {
67666      var target, transform = this._currentTransform,
67667          groupSelector = this._groupSelector, shouldRender = false,
67668          isClick = (!groupSelector || (groupSelector.left === 0 && groupSelector.top === 0));
67669      this._cacheTransformEventData(e);
67670      target = this._target;
67671      this._handleEvent(e, 'up:before');
67672      // if right/middle click just fire events and return
67673      // target undefined will make the _handleEvent search the target
67674      if (checkClick(e, RIGHT_CLICK)) {
67675        if (this.fireRightClick) {
67676          this._handleEvent(e, 'up', RIGHT_CLICK, isClick);
67677        }
67678        return;
67679      }
67680
67681      if (checkClick(e, MIDDLE_CLICK)) {
67682        if (this.fireMiddleClick) {
67683          this._handleEvent(e, 'up', MIDDLE_CLICK, isClick);
67684        }
67685        this._resetTransformEventData();
67686        return;
67687      }
67688
67689      if (this.isDrawingMode && this._isCurrentlyDrawing) {
67690        this._onMouseUpInDrawingMode(e);
67691        return;
67692      }
67693
67694      if (!this._isMainEvent(e)) {
67695        return;
67696      }
67697      if (transform) {
67698        this._finalizeCurrentTransform(e);
67699        shouldRender = transform.actionPerformed;
67700      }
67701      if (!isClick) {
67702        var targetWasActive = target === this._activeObject;
67703        this._maybeGroupObjects(e);
67704        if (!shouldRender) {
67705          shouldRender = (
67706            this._shouldRender(target) ||
67707            (!targetWasActive && target === this._activeObject)
67708          );
67709        }
67710      }
67711      if (target) {
67712        if (target.selectable && target !== this._activeObject && target.activeOn === 'up') {
67713          this.setActiveObject(target, e);
67714          shouldRender = true;
67715        }
67716        else {
67717          var corner = target._findTargetCorner(
67718            this.getPointer(e, true),
67719            fabric.util.isTouchEvent(e)
67720          );
67721          var control = target.controls[corner],
67722              mouseUpHandler = control && control.getMouseUpHandler(e, target, control);
67723          if (mouseUpHandler) {
67724            var pointer = this.getPointer(e);
67725            mouseUpHandler(e, transform, pointer.x, pointer.y);
67726          }
67727        }
67728        target.isMoving = false;
67729      }
67730      this._setCursorFromEvent(e, target);
67731      this._handleEvent(e, 'up', LEFT_CLICK, isClick);
67732      this._groupSelector = null;
67733      this._currentTransform = null;
67734      // reset the target information about which corner is selected
67735      target && (target.__corner = 0);
67736      if (shouldRender) {
67737        this.requestRenderAll();
67738      }
67739      else if (!isClick) {
67740        this.renderTop();
67741      }
67742    },
67743
67744    /**
67745     * @private
67746     * Handle event firing for target and subtargets
67747     * @param {Event} e event from mouse
67748     * @param {String} eventType event to fire (up, down or move)
67749     * @return {Fabric.Object} target return the the target found, for internal reasons.
67750     */
67751    _simpleEventHandler: function(eventType, e) {
67752      var target = this.findTarget(e),
67753          targets = this.targets,
67754          options = {
67755            e: e,
67756            target: target,
67757            subTargets: targets,
67758          };
67759      this.fire(eventType, options);
67760      target && target.fire(eventType, options);
67761      if (!targets) {
67762        return target;
67763      }
67764      for (var i = 0; i < targets.length; i++) {
67765        targets[i].fire(eventType, options);
67766      }
67767      return target;
67768    },
67769
67770    /**
67771     * @private
67772     * Handle event firing for target and subtargets
67773     * @param {Event} e event from mouse
67774     * @param {String} eventType event to fire (up, down or move)
67775     * @param {fabric.Object} targetObj receiving event
67776     * @param {Number} [button] button used in the event 1 = left, 2 = middle, 3 = right
67777     * @param {Boolean} isClick for left button only, indicates that the mouse up happened without move.
67778     */
67779    _handleEvent: function(e, eventType, button, isClick) {
67780      var target = this._target,
67781          targets = this.targets || [],
67782          options = {
67783            e: e,
67784            target: target,
67785            subTargets: targets,
67786            button: button || LEFT_CLICK,
67787            isClick: isClick || false,
67788            pointer: this._pointer,
67789            absolutePointer: this._absolutePointer,
67790            transform: this._currentTransform
67791          };
67792      if (eventType === 'up') {
67793        options.currentTarget = this.findTarget(e);
67794        options.currentSubTargets = this.targets;
67795      }
67796      this.fire('mouse:' + eventType, options);
67797      target && target.fire('mouse' + eventType, options);
67798      for (var i = 0; i < targets.length; i++) {
67799        targets[i].fire('mouse' + eventType, options);
67800      }
67801    },
67802
67803    /**
67804     * @private
67805     * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event
67806     */
67807    _finalizeCurrentTransform: function(e) {
67808
67809      var transform = this._currentTransform,
67810          target = transform.target,
67811          eventName,
67812          options = {
67813            e: e,
67814            target: target,
67815            transform: transform,
67816            action: transform.action,
67817          };
67818
67819      if (target._scaling) {
67820        target._scaling = false;
67821      }
67822
67823      target.setCoords();
67824
67825      if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) {
67826        if (transform.actionPerformed) {
67827          // this is not friendly to the new control api.
67828          // is deprecated.
67829          eventName = this._addEventOptions(options, transform);
67830          this._fire(eventName, options);
67831        }
67832        this._fire('modified', options);
67833      }
67834    },
67835
67836    /**
67837     * Mutate option object in order to add by property and give back the event name.
67838     * @private
67839     * @deprecated since 4.2.0
67840     * @param {Object} options to mutate
67841     * @param {Object} transform to inspect action from
67842     */
67843    _addEventOptions: function(options, transform) {
67844      // we can probably add more details at low cost
67845      // scale change, rotation changes, translation changes
67846      var eventName, by;
67847      switch (transform.action) {
67848        case 'scaleX':
67849          eventName = 'scaled';
67850          by = 'x';
67851          break;
67852        case 'scaleY':
67853          eventName = 'scaled';
67854          by = 'y';
67855          break;
67856        case 'skewX':
67857          eventName = 'skewed';
67858          by = 'x';
67859          break;
67860        case 'skewY':
67861          eventName = 'skewed';
67862          by = 'y';
67863          break;
67864        case 'scale':
67865          eventName = 'scaled';
67866          by = 'equally';
67867          break;
67868        case 'rotate':
67869          eventName = 'rotated';
67870          break;
67871        case 'drag':
67872          eventName = 'moved';
67873          break;
67874      }
67875      options.by = by;
67876      return eventName;
67877    },
67878
67879    /**
67880     * @private
67881     * @param {Event} e Event object fired on mousedown
67882     */
67883    _onMouseDownInDrawingMode: function(e) {
67884      this._isCurrentlyDrawing = true;
67885      if (this.getActiveObject()) {
67886        this.discardActiveObject(e).requestRenderAll();
67887      }
67888      var pointer = this.getPointer(e);
67889      this.freeDrawingBrush.onMouseDown(pointer, { e: e, pointer: pointer });
67890      this._handleEvent(e, 'down');
67891    },
67892
67893    /**
67894     * @private
67895     * @param {Event} e Event object fired on mousemove
67896     */
67897    _onMouseMoveInDrawingMode: function(e) {
67898      if (this._isCurrentlyDrawing) {
67899        var pointer = this.getPointer(e);
67900        this.freeDrawingBrush.onMouseMove(pointer, { e: e, pointer: pointer });
67901      }
67902      this.setCursor(this.freeDrawingCursor);
67903      this._handleEvent(e, 'move');
67904    },
67905
67906    /**
67907     * @private
67908     * @param {Event} e Event object fired on mouseup
67909     */
67910    _onMouseUpInDrawingMode: function(e) {
67911      var pointer = this.getPointer(e);
67912      this._isCurrentlyDrawing = this.freeDrawingBrush.onMouseUp({ e: e, pointer: pointer });
67913      this._handleEvent(e, 'up');
67914    },
67915
67916    /**
67917     * Method that defines the actions when mouse is clicked on canvas.
67918     * The method inits the currentTransform parameters and renders all the
67919     * canvas so the current image can be placed on the top canvas and the rest
67920     * in on the container one.
67921     * @private
67922     * @param {Event} e Event object fired on mousedown
67923     */
67924    __onMouseDown: function (e) {
67925      this._cacheTransformEventData(e);
67926      this._handleEvent(e, 'down:before');
67927      var target = this._target;
67928      // if right click just fire events
67929      if (checkClick(e, RIGHT_CLICK)) {
67930        if (this.fireRightClick) {
67931          this._handleEvent(e, 'down', RIGHT_CLICK);
67932        }
67933        return;
67934      }
67935
67936      if (checkClick(e, MIDDLE_CLICK)) {
67937        if (this.fireMiddleClick) {
67938          this._handleEvent(e, 'down', MIDDLE_CLICK);
67939        }
67940        return;
67941      }
67942
67943      if (this.isDrawingMode) {
67944        this._onMouseDownInDrawingMode(e);
67945        return;
67946      }
67947
67948      if (!this._isMainEvent(e)) {
67949        return;
67950      }
67951
67952      // ignore if some object is being transformed at this moment
67953      if (this._currentTransform) {
67954        return;
67955      }
67956
67957      var pointer = this._pointer;
67958      // save pointer for check in __onMouseUp event
67959      this._previousPointer = pointer;
67960      var shouldRender = this._shouldRender(target),
67961          shouldGroup = this._shouldGroup(e, target);
67962      if (this._shouldClearSelection(e, target)) {
67963        this.discardActiveObject(e);
67964      }
67965      else if (shouldGroup) {
67966        this._handleGrouping(e, target);
67967        target = this._activeObject;
67968      }
67969
67970      if (this.selection && (!target ||
67971        (!target.selectable && !target.isEditing && target !== this._activeObject))) {
67972        this._groupSelector = {
67973          ex: this._absolutePointer.x,
67974          ey: this._absolutePointer.y,
67975          top: 0,
67976          left: 0
67977        };
67978      }
67979
67980      if (target) {
67981        var alreadySelected = target === this._activeObject;
67982        if (target.selectable && target.activeOn === 'down') {
67983          this.setActiveObject(target, e);
67984        }
67985        var corner = target._findTargetCorner(
67986          this.getPointer(e, true),
67987          fabric.util.isTouchEvent(e)
67988        );
67989        target.__corner = corner;
67990        if (target === this._activeObject && (corner || !shouldGroup)) {
67991          this._setupCurrentTransform(e, target, alreadySelected);
67992          var control = target.controls[corner],
67993              pointer = this.getPointer(e),
67994              mouseDownHandler = control && control.getMouseDownHandler(e, target, control);
67995          if (mouseDownHandler) {
67996            mouseDownHandler(e, this._currentTransform, pointer.x, pointer.y);
67997          }
67998        }
67999      }
68000      this._handleEvent(e, 'down');
68001      // we must renderAll so that we update the visuals
68002      (shouldRender || shouldGroup) && this.requestRenderAll();
68003    },
68004
68005    /**
68006     * reset cache form common information needed during event processing
68007     * @private
68008     */
68009    _resetTransformEventData: function() {
68010      this._target = null;
68011      this._pointer = null;
68012      this._absolutePointer = null;
68013    },
68014
68015    /**
68016     * Cache common information needed during event processing
68017     * @private
68018     * @param {Event} e Event object fired on event
68019     */
68020    _cacheTransformEventData: function(e) {
68021      // reset in order to avoid stale caching
68022      this._resetTransformEventData();
68023      this._pointer = this.getPointer(e, true);
68024      this._absolutePointer = this.restorePointerVpt(this._pointer);
68025      this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(e) || null;
68026    },
68027
68028    /**
68029     * @private
68030     */
68031    _beforeTransform: function(e) {
68032      var t = this._currentTransform;
68033      this.stateful && t.target.saveState();
68034      this.fire('before:transform', {
68035        e: e,
68036        transform: t,
68037      });
68038    },
68039
68040    /**
68041     * Method that defines the actions when mouse is hovering the canvas.
68042     * The currentTransform parameter will define whether the user is rotating/scaling/translating
68043     * an image or neither of them (only hovering). A group selection is also possible and would cancel
68044     * all any other type of action.
68045     * In case of an image transformation only the top canvas will be rendered.
68046     * @private
68047     * @param {Event} e Event object fired on mousemove
68048     */
68049    __onMouseMove: function (e) {
68050      this._handleEvent(e, 'move:before');
68051      this._cacheTransformEventData(e);
68052      var target, pointer;
68053
68054      if (this.isDrawingMode) {
68055        this._onMouseMoveInDrawingMode(e);
68056        return;
68057      }
68058
68059      if (!this._isMainEvent(e)) {
68060        return;
68061      }
68062
68063      var groupSelector = this._groupSelector;
68064
68065      // We initially clicked in an empty area, so we draw a box for multiple selection
68066      if (groupSelector) {
68067        pointer = this._absolutePointer;
68068
68069        groupSelector.left = pointer.x - groupSelector.ex;
68070        groupSelector.top = pointer.y - groupSelector.ey;
68071
68072        this.renderTop();
68073      }
68074      else if (!this._currentTransform) {
68075        target = this.findTarget(e) || null;
68076        this._setCursorFromEvent(e, target);
68077        this._fireOverOutEvents(target, e);
68078      }
68079      else {
68080        this._transformObject(e);
68081      }
68082      this._handleEvent(e, 'move');
68083      this._resetTransformEventData();
68084    },
68085
68086    /**
68087     * Manage the mouseout, mouseover events for the fabric object on the canvas
68088     * @param {Fabric.Object} target the target where the target from the mousemove event
68089     * @param {Event} e Event object fired on mousemove
68090     * @private
68091     */
68092    _fireOverOutEvents: function(target, e) {
68093      var _hoveredTarget = this._hoveredTarget,
68094          _hoveredTargets = this._hoveredTargets, targets = this.targets,
68095          length = Math.max(_hoveredTargets.length, targets.length);
68096
68097      this.fireSyntheticInOutEvents(target, e, {
68098        oldTarget: _hoveredTarget,
68099        evtOut: 'mouseout',
68100        canvasEvtOut: 'mouse:out',
68101        evtIn: 'mouseover',
68102        canvasEvtIn: 'mouse:over',
68103      });
68104      for (var i = 0; i < length; i++){
68105        this.fireSyntheticInOutEvents(targets[i], e, {
68106          oldTarget: _hoveredTargets[i],
68107          evtOut: 'mouseout',
68108          evtIn: 'mouseover',
68109        });
68110      }
68111      this._hoveredTarget = target;
68112      this._hoveredTargets = this.targets.concat();
68113    },
68114
68115    /**
68116     * Manage the dragEnter, dragLeave events for the fabric objects on the canvas
68117     * @param {Fabric.Object} target the target where the target from the onDrag event
68118     * @param {Event} e Event object fired on ondrag
68119     * @private
68120     */
68121    _fireEnterLeaveEvents: function(target, e) {
68122      var _draggedoverTarget = this._draggedoverTarget,
68123          _hoveredTargets = this._hoveredTargets, targets = this.targets,
68124          length = Math.max(_hoveredTargets.length, targets.length);
68125
68126      this.fireSyntheticInOutEvents(target, e, {
68127        oldTarget: _draggedoverTarget,
68128        evtOut: 'dragleave',
68129        evtIn: 'dragenter',
68130      });
68131      for (var i = 0; i < length; i++) {
68132        this.fireSyntheticInOutEvents(targets[i], e, {
68133          oldTarget: _hoveredTargets[i],
68134          evtOut: 'dragleave',
68135          evtIn: 'dragenter',
68136        });
68137      }
68138      this._draggedoverTarget = target;
68139    },
68140
68141    /**
68142     * Manage the synthetic in/out events for the fabric objects on the canvas
68143     * @param {Fabric.Object} target the target where the target from the supported events
68144     * @param {Event} e Event object fired
68145     * @param {Object} config configuration for the function to work
68146     * @param {String} config.targetName property on the canvas where the old target is stored
68147     * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out
68148     * @param {String} config.evtOut name of the event to fire for out
68149     * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in
68150     * @param {String} config.evtIn name of the event to fire for in
68151     * @private
68152     */
68153    fireSyntheticInOutEvents: function(target, e, config) {
68154      var inOpt, outOpt, oldTarget = config.oldTarget, outFires, inFires,
68155          targetChanged = oldTarget !== target, canvasEvtIn = config.canvasEvtIn, canvasEvtOut = config.canvasEvtOut;
68156      if (targetChanged) {
68157        inOpt = { e: e, target: target, previousTarget: oldTarget };
68158        outOpt = { e: e, target: oldTarget, nextTarget: target };
68159      }
68160      inFires = target && targetChanged;
68161      outFires = oldTarget && targetChanged;
68162      if (outFires) {
68163        canvasEvtOut && this.fire(canvasEvtOut, outOpt);
68164        oldTarget.fire(config.evtOut, outOpt);
68165      }
68166      if (inFires) {
68167        canvasEvtIn && this.fire(canvasEvtIn, inOpt);
68168        target.fire(config.evtIn, inOpt);
68169      }
68170    },
68171
68172    /**
68173     * Method that defines actions when an Event Mouse Wheel
68174     * @param {Event} e Event object fired on mouseup
68175     */
68176    __onMouseWheel: function(e) {
68177      this._cacheTransformEventData(e);
68178      this._handleEvent(e, 'wheel');
68179      this._resetTransformEventData();
68180    },
68181
68182    /**
68183     * @private
68184     * @param {Event} e Event fired on mousemove
68185     */
68186    _transformObject: function(e) {
68187      var pointer = this.getPointer(e),
68188          transform = this._currentTransform;
68189
68190      transform.reset = false;
68191      transform.shiftKey = e.shiftKey;
68192      transform.altKey = e[this.centeredKey];
68193
68194      this._performTransformAction(e, transform, pointer);
68195      transform.actionPerformed && this.requestRenderAll();
68196    },
68197
68198    /**
68199     * @private
68200     */
68201    _performTransformAction: function(e, transform, pointer) {
68202      var x = pointer.x,
68203          y = pointer.y,
68204          action = transform.action,
68205          actionPerformed = false,
68206          actionHandler = transform.actionHandler;
68207          // this object could be created from the function in the control handlers
68208
68209
68210      if (actionHandler) {
68211        actionPerformed = actionHandler(e, transform, x, y);
68212      }
68213      if (action === 'drag' && actionPerformed) {
68214        transform.target.isMoving = true;
68215        this.setCursor(transform.target.moveCursor || this.moveCursor);
68216      }
68217      transform.actionPerformed = transform.actionPerformed || actionPerformed;
68218    },
68219
68220    /**
68221     * @private
68222     */
68223    _fire: fabric.controlsUtils.fireEvent,
68224
68225    /**
68226     * Sets the cursor depending on where the canvas is being hovered.
68227     * Note: very buggy in Opera
68228     * @param {Event} e Event object
68229     * @param {Object} target Object that the mouse is hovering, if so.
68230     */
68231    _setCursorFromEvent: function (e, target) {
68232      if (!target) {
68233        this.setCursor(this.defaultCursor);
68234        return false;
68235      }
68236      var hoverCursor = target.hoverCursor || this.hoverCursor,
68237          activeSelection = this._activeObject && this._activeObject.type === 'activeSelection' ?
68238            this._activeObject : null,
68239          // only show proper corner when group selection is not active
68240          corner = (!activeSelection || !activeSelection.contains(target))
68241          // here we call findTargetCorner always with undefined for the touch parameter.
68242          // we assume that if you are using a cursor you do not need to interact with
68243          // the bigger touch area.
68244                    && target._findTargetCorner(this.getPointer(e, true));
68245
68246      if (!corner) {
68247        if (target.subTargetCheck){
68248          // hoverCursor should come from top-most subTarget,
68249          // so we walk the array backwards
68250          this.targets.concat().reverse().map(function(_target){
68251            hoverCursor = _target.hoverCursor || hoverCursor;
68252          });
68253        }
68254        this.setCursor(hoverCursor);
68255      }
68256      else {
68257        this.setCursor(this.getCornerCursor(corner, target, e));
68258      }
68259    },
68260
68261    /**
68262     * @private
68263     */
68264    getCornerCursor: function(corner, target, e) {
68265      var control = target.controls[corner];
68266      return control.cursorStyleHandler(e, control, target);
68267    }
68268  });
68269})();
68270
68271
68272(function() {
68273
68274  var min = Math.min,
68275      max = Math.max;
68276
68277  fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {
68278
68279    /**
68280     * @private
68281     * @param {Event} e Event object
68282     * @param {fabric.Object} target
68283     * @return {Boolean}
68284     */
68285    _shouldGroup: function(e, target) {
68286      var activeObject = this._activeObject;
68287      return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection &&
68288            (activeObject !== target || activeObject.type === 'activeSelection') && !target.onSelect({ e: e });
68289    },
68290
68291    /**
68292     * @private
68293     * @param {Event} e Event object
68294     * @param {fabric.Object} target
68295     */
68296    _handleGrouping: function (e, target) {
68297      var activeObject = this._activeObject;
68298      // avoid multi select when shift click on a corner
68299      if (activeObject.__corner) {
68300        return;
68301      }
68302      if (target === activeObject) {
68303        // if it's a group, find target again, using activeGroup objects
68304        target = this.findTarget(e, true);
68305        // if even object is not found or we are on activeObjectCorner, bail out
68306        if (!target || !target.selectable) {
68307          return;
68308        }
68309      }
68310      if (activeObject && activeObject.type === 'activeSelection') {
68311        this._updateActiveSelection(target, e);
68312      }
68313      else {
68314        this._createActiveSelection(target, e);
68315      }
68316    },
68317
68318    /**
68319     * @private
68320     */
68321    _updateActiveSelection: function(target, e) {
68322      var activeSelection = this._activeObject,
68323          currentActiveObjects = activeSelection._objects.slice(0);
68324      if (activeSelection.contains(target)) {
68325        activeSelection.removeWithUpdate(target);
68326        this._hoveredTarget = target;
68327        this._hoveredTargets = this.targets.concat();
68328        if (activeSelection.size() === 1) {
68329          // activate last remaining object
68330          this._setActiveObject(activeSelection.item(0), e);
68331        }
68332      }
68333      else {
68334        activeSelection.addWithUpdate(target);
68335        this._hoveredTarget = activeSelection;
68336        this._hoveredTargets = this.targets.concat();
68337      }
68338      this._fireSelectionEvents(currentActiveObjects, e);
68339    },
68340
68341    /**
68342     * @private
68343     */
68344    _createActiveSelection: function(target, e) {
68345      var currentActives = this.getActiveObjects(), group = this._createGroup(target);
68346      this._hoveredTarget = group;
68347      // ISSUE 4115: should we consider subTargets here?
68348      // this._hoveredTargets = [];
68349      // this._hoveredTargets = this.targets.concat();
68350      this._setActiveObject(group, e);
68351      this._fireSelectionEvents(currentActives, e);
68352    },
68353
68354    /**
68355     * @private
68356     * @param {Object} target
68357     */
68358    _createGroup: function(target) {
68359      var objects = this._objects,
68360          isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target),
68361          groupObjects = isActiveLower
68362            ? [this._activeObject, target]
68363            : [target, this._activeObject];
68364      this._activeObject.isEditing && this._activeObject.exitEditing();
68365      return new fabric.ActiveSelection(groupObjects, {
68366        canvas: this
68367      });
68368    },
68369
68370    /**
68371     * @private
68372     * @param {Event} e mouse event
68373     */
68374    _groupSelectedObjects: function (e) {
68375
68376      var group = this._collectObjects(e),
68377          aGroup;
68378
68379      // do not create group for 1 element only
68380      if (group.length === 1) {
68381        this.setActiveObject(group[0], e);
68382      }
68383      else if (group.length > 1) {
68384        aGroup = new fabric.ActiveSelection(group.reverse(), {
68385          canvas: this
68386        });
68387        this.setActiveObject(aGroup, e);
68388      }
68389    },
68390
68391    /**
68392     * @private
68393     */
68394    _collectObjects: function(e) {
68395      var group = [],
68396          currentObject,
68397          x1 = this._groupSelector.ex,
68398          y1 = this._groupSelector.ey,
68399          x2 = x1 + this._groupSelector.left,
68400          y2 = y1 + this._groupSelector.top,
68401          selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)),
68402          selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)),
68403          allowIntersect = !this.selectionFullyContained,
68404          isClick = x1 === x2 && y1 === y2;
68405      // we iterate reverse order to collect top first in case of click.
68406      for (var i = this._objects.length; i--; ) {
68407        currentObject = this._objects[i];
68408
68409        if (!currentObject || !currentObject.selectable || !currentObject.visible) {
68410          continue;
68411        }
68412
68413        if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2, true)) ||
68414            currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2, true) ||
68415            (allowIntersect && currentObject.containsPoint(selectionX1Y1, null, true)) ||
68416            (allowIntersect && currentObject.containsPoint(selectionX2Y2, null, true))
68417        ) {
68418          group.push(currentObject);
68419          // only add one object if it's a click
68420          if (isClick) {
68421            break;
68422          }
68423        }
68424      }
68425
68426      if (group.length > 1) {
68427        group = group.filter(function(object) {
68428          return !object.onSelect({ e: e });
68429        });
68430      }
68431
68432      return group;
68433    },
68434
68435    /**
68436     * @private
68437     */
68438    _maybeGroupObjects: function(e) {
68439      if (this.selection && this._groupSelector) {
68440        this._groupSelectedObjects(e);
68441      }
68442      this.setCursor(this.defaultCursor);
68443      // clear selection and current transformation
68444      this._groupSelector = null;
68445    }
68446  });
68447
68448})();
68449
68450
68451(function () {
68452  fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {
68453
68454    /**
68455     * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately
68456     * @param {Object} [options] Options object
68457     * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png"
68458     * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.
68459     * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent
68460     * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14
68461     * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14
68462     * @param {Number} [options.width] Cropping width. Introduced in v1.2.14
68463     * @param {Number} [options.height] Cropping height. Introduced in v1.2.14
68464     * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0
68465     * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format
68466     * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo}
68467     * @example <caption>Generate jpeg dataURL with lower quality</caption>
68468     * var dataURL = canvas.toDataURL({
68469     *   format: 'jpeg',
68470     *   quality: 0.8
68471     * });
68472     * @example <caption>Generate cropped png dataURL (clipping of canvas)</caption>
68473     * var dataURL = canvas.toDataURL({
68474     *   format: 'png',
68475     *   left: 100,
68476     *   top: 100,
68477     *   width: 200,
68478     *   height: 200
68479     * });
68480     * @example <caption>Generate double scaled png dataURL</caption>
68481     * var dataURL = canvas.toDataURL({
68482     *   format: 'png',
68483     *   multiplier: 2
68484     * });
68485     */
68486    toDataURL: function (options) {
68487      options || (options = { });
68488
68489      var format = options.format || 'png',
68490          quality = options.quality || 1,
68491          multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? this.getRetinaScaling() : 1),
68492          canvasEl = this.toCanvasElement(multiplier, options);
68493      return fabric.util.toDataURL(canvasEl, format, quality);
68494    },
68495
68496    /**
68497     * Create a new HTMLCanvas element painted with the current canvas content.
68498     * No need to resize the actual one or repaint it.
68499     * Will transfer object ownership to a new canvas, paint it, and set everything back.
68500     * This is an intermediary step used to get to a dataUrl but also it is useful to
68501     * create quick image copies of a canvas without passing for the dataUrl string
68502     * @param {Number} [multiplier] a zoom factor.
68503     * @param {Object} [cropping] Cropping informations
68504     * @param {Number} [cropping.left] Cropping left offset.
68505     * @param {Number} [cropping.top] Cropping top offset.
68506     * @param {Number} [cropping.width] Cropping width.
68507     * @param {Number} [cropping.height] Cropping height.
68508     */
68509    toCanvasElement: function(multiplier, cropping) {
68510      multiplier = multiplier || 1;
68511      cropping = cropping || { };
68512      var scaledWidth = (cropping.width || this.width) * multiplier,
68513          scaledHeight = (cropping.height || this.height) * multiplier,
68514          zoom = this.getZoom(),
68515          originalWidth = this.width,
68516          originalHeight = this.height,
68517          newZoom = zoom * multiplier,
68518          vp = this.viewportTransform,
68519          translateX = (vp[4] - (cropping.left || 0)) * multiplier,
68520          translateY = (vp[5] - (cropping.top || 0)) * multiplier,
68521          originalInteractive = this.interactive,
68522          newVp = [newZoom, 0, 0, newZoom, translateX, translateY],
68523          originalRetina = this.enableRetinaScaling,
68524          canvasEl = fabric.util.createCanvasElement(),
68525          originalContextTop = this.contextTop;
68526      canvasEl.width = scaledWidth;
68527      canvasEl.height = scaledHeight;
68528      this.contextTop = null;
68529      this.enableRetinaScaling = false;
68530      this.interactive = false;
68531      this.viewportTransform = newVp;
68532      this.width = scaledWidth;
68533      this.height = scaledHeight;
68534      this.calcViewportBoundaries();
68535      this.renderCanvas(canvasEl.getContext('2d'), this._objects);
68536      this.viewportTransform = vp;
68537      this.width = originalWidth;
68538      this.height = originalHeight;
68539      this.calcViewportBoundaries();
68540      this.interactive = originalInteractive;
68541      this.enableRetinaScaling = originalRetina;
68542      this.contextTop = originalContextTop;
68543      return canvasEl;
68544    },
68545  });
68546
68547})();
68548
68549
68550fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {
68551  /**
68552   * Populates canvas with data from the specified JSON.
68553   * JSON format must conform to the one of {@link fabric.Canvas#toJSON}
68554   * @param {String|Object} json JSON string or object
68555   * @param {Function} callback Callback, invoked when json is parsed
68556   *                            and corresponding objects (e.g: {@link fabric.Image})
68557   *                            are initialized
68558   * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.
68559   * @return {fabric.Canvas} instance
68560   * @chainable
68561   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}
68562   * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}
68563   * @example <caption>loadFromJSON</caption>
68564   * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));
68565   * @example <caption>loadFromJSON with reviver</caption>
68566   * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(o, object) {
68567   *   // `o` = json object
68568   *   // `object` = fabric.Object instance
68569   *   // ... do some stuff ...
68570   * });
68571   */
68572  loadFromJSON: function (json, callback, reviver) {
68573    if (!json) {
68574      return;
68575    }
68576
68577    // serialize if it wasn't already
68578    var serialized = (typeof json === 'string')
68579      ? JSON.parse(json)
68580      : fabric.util.object.clone(json);
68581
68582    var _this = this,
68583        clipPath = serialized.clipPath,
68584        renderOnAddRemove = this.renderOnAddRemove;
68585
68586    this.renderOnAddRemove = false;
68587
68588    delete serialized.clipPath;
68589
68590    this._enlivenObjects(serialized.objects, function (enlivenedObjects) {
68591      _this.clear();
68592      _this._setBgOverlay(serialized, function () {
68593        if (clipPath) {
68594          _this._enlivenObjects([clipPath], function (enlivenedCanvasClip) {
68595            _this.clipPath = enlivenedCanvasClip[0];
68596            _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback);
68597          });
68598        }
68599        else {
68600          _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback);
68601        }
68602      });
68603    }, reviver);
68604    return this;
68605  },
68606
68607  /**
68608   * @private
68609   * @param {Object} serialized Object with background and overlay information
68610   * @param {Array} restored canvas objects
68611   * @param {Function} cached renderOnAddRemove callback
68612   * @param {Function} callback Invoked after all background and overlay images/patterns loaded
68613   */
68614  __setupCanvas: function(serialized, enlivenedObjects, renderOnAddRemove, callback) {
68615    var _this = this;
68616    enlivenedObjects.forEach(function(obj, index) {
68617      // we splice the array just in case some custom classes restored from JSON
68618      // will add more object to canvas at canvas init.
68619      _this.insertAt(obj, index);
68620    });
68621    this.renderOnAddRemove = renderOnAddRemove;
68622    // remove parts i cannot set as options
68623    delete serialized.objects;
68624    delete serialized.backgroundImage;
68625    delete serialized.overlayImage;
68626    delete serialized.background;
68627    delete serialized.overlay;
68628    // this._initOptions does too many things to just
68629    // call it. Normally loading an Object from JSON
68630    // create the Object instance. Here the Canvas is
68631    // already an instance and we are just loading things over it
68632    this._setOptions(serialized);
68633    this.renderAll();
68634    callback && callback();
68635  },
68636
68637  /**
68638   * @private
68639   * @param {Object} serialized Object with background and overlay information
68640   * @param {Function} callback Invoked after all background and overlay images/patterns loaded
68641   */
68642  _setBgOverlay: function(serialized, callback) {
68643    var loaded = {
68644      backgroundColor: false,
68645      overlayColor: false,
68646      backgroundImage: false,
68647      overlayImage: false
68648    };
68649
68650    if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) {
68651      callback && callback();
68652      return;
68653    }
68654
68655    var cbIfLoaded = function () {
68656      if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) {
68657        callback && callback();
68658      }
68659    };
68660
68661    this.__setBgOverlay('backgroundImage', serialized.backgroundImage, loaded, cbIfLoaded);
68662    this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded);
68663    this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded);
68664    this.__setBgOverlay('overlayColor', serialized.overlay, loaded, cbIfLoaded);
68665  },
68666
68667  /**
68668   * @private
68669   * @param {String} property Property to set (backgroundImage, overlayImage, backgroundColor, overlayColor)
68670   * @param {(Object|String)} value Value to set
68671   * @param {Object} loaded Set loaded property to true if property is set
68672   * @param {Object} callback Callback function to invoke after property is set
68673   */
68674  __setBgOverlay: function(property, value, loaded, callback) {
68675    var _this = this;
68676
68677    if (!value) {
68678      loaded[property] = true;
68679      callback && callback();
68680      return;
68681    }
68682
68683    if (property === 'backgroundImage' || property === 'overlayImage') {
68684      fabric.util.enlivenObjects([value], function(enlivedObject){
68685        _this[property] = enlivedObject[0];
68686        loaded[property] = true;
68687        callback && callback();
68688      });
68689    }
68690    else {
68691      this['set' + fabric.util.string.capitalize(property, true)](value, function() {
68692        loaded[property] = true;
68693        callback && callback();
68694      });
68695    }
68696  },
68697
68698  /**
68699   * @private
68700   * @param {Array} objects
68701   * @param {Function} callback
68702   * @param {Function} [reviver]
68703   */
68704  _enlivenObjects: function (objects, callback, reviver) {
68705    if (!objects || objects.length === 0) {
68706      callback && callback([]);
68707      return;
68708    }
68709
68710    fabric.util.enlivenObjects(objects, function(enlivenedObjects) {
68711      callback && callback(enlivenedObjects);
68712    }, null, reviver);
68713  },
68714
68715  /**
68716   * @private
68717   * @param {String} format
68718   * @param {Function} callback
68719   */
68720  _toDataURL: function (format, callback) {
68721    this.clone(function (clone) {
68722      callback(clone.toDataURL(format));
68723    });
68724  },
68725
68726  /**
68727   * @private
68728   * @param {String} format
68729   * @param {Number} multiplier
68730   * @param {Function} callback
68731   */
68732  _toDataURLWithMultiplier: function (format, multiplier, callback) {
68733    this.clone(function (clone) {
68734      callback(clone.toDataURLWithMultiplier(format, multiplier));
68735    });
68736  },
68737
68738  /**
68739   * Clones canvas instance
68740   * @param {Object} [callback] Receives cloned instance as a first argument
68741   * @param {Array} [properties] Array of properties to include in the cloned canvas and children
68742   */
68743  clone: function (callback, properties) {
68744    var data = JSON.stringify(this.toJSON(properties));
68745    this.cloneWithoutData(function(clone) {
68746      clone.loadFromJSON(data, function() {
68747        callback && callback(clone);
68748      });
68749    });
68750  },
68751
68752  /**
68753   * Clones canvas instance without cloning existing data.
68754   * This essentially copies canvas dimensions, clipping properties, etc.
68755   * but leaves data empty (so that you can populate it with your own)
68756   * @param {Object} [callback] Receives cloned instance as a first argument
68757   */
68758  cloneWithoutData: function(callback) {
68759    var el = fabric.util.createCanvasElement();
68760
68761    el.width = this.width;
68762    el.height = this.height;
68763
68764    var clone = new fabric.Canvas(el);
68765    if (this.backgroundImage) {
68766      clone.setBackgroundImage(this.backgroundImage.src, function() {
68767        clone.renderAll();
68768        callback && callback(clone);
68769      });
68770      clone.backgroundImageOpacity = this.backgroundImageOpacity;
68771      clone.backgroundImageStretch = this.backgroundImageStretch;
68772    }
68773    else {
68774      callback && callback(clone);
68775    }
68776  }
68777});
68778
68779
68780(function(global) {
68781
68782  'use strict';
68783
68784  var fabric = global.fabric || (global.fabric = { }),
68785      extend = fabric.util.object.extend,
68786      clone = fabric.util.object.clone,
68787      toFixed = fabric.util.toFixed,
68788      capitalize = fabric.util.string.capitalize,
68789      degreesToRadians = fabric.util.degreesToRadians,
68790      objectCaching = !fabric.isLikelyNode,
68791      ALIASING_LIMIT = 2;
68792
68793  if (fabric.Object) {
68794    return;
68795  }
68796
68797  /**
68798   * Root object class from which all 2d shape classes inherit from
68799   * @class fabric.Object
68800   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}
68801   * @see {@link fabric.Object#initialize} for constructor definition
68802   *
68803   * @fires added
68804   * @fires removed
68805   *
68806   * @fires selected
68807   * @fires deselected
68808   * @fires modified
68809   * @fires modified
68810   * @fires moved
68811   * @fires scaled
68812   * @fires rotated
68813   * @fires skewed
68814   *
68815   * @fires rotating
68816   * @fires scaling
68817   * @fires moving
68818   * @fires skewing
68819   *
68820   * @fires mousedown
68821   * @fires mouseup
68822   * @fires mouseover
68823   * @fires mouseout
68824   * @fires mousewheel
68825   * @fires mousedblclick
68826   *
68827   * @fires dragover
68828   * @fires dragenter
68829   * @fires dragleave
68830   * @fires drop
68831   */
68832  fabric.Object = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.Object.prototype */ {
68833
68834    /**
68835     * Type of an object (rect, circle, path, etc.).
68836     * Note that this property is meant to be read-only and not meant to be modified.
68837     * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly.
68838     * @type String
68839     * @default
68840     */
68841    type:                     'object',
68842
68843    /**
68844     * Horizontal origin of transformation of an object (one of "left", "right", "center")
68845     * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups
68846     * @type String
68847     * @default
68848     */
68849    originX:                  'left',
68850
68851    /**
68852     * Vertical origin of transformation of an object (one of "top", "bottom", "center")
68853     * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups
68854     * @type String
68855     * @default
68856     */
68857    originY:                  'top',
68858
68859    /**
68860     * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom}
68861     * @type Number
68862     * @default
68863     */
68864    top:                      0,
68865
68866    /**
68867     * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right}
68868     * @type Number
68869     * @default
68870     */
68871    left:                     0,
68872
68873    /**
68874     * Object width
68875     * @type Number
68876     * @default
68877     */
68878    width:                    0,
68879
68880    /**
68881     * Object height
68882     * @type Number
68883     * @default
68884     */
68885    height:                   0,
68886
68887    /**
68888     * Object scale factor (horizontal)
68889     * @type Number
68890     * @default
68891     */
68892    scaleX:                   1,
68893
68894    /**
68895     * Object scale factor (vertical)
68896     * @type Number
68897     * @default
68898     */
68899    scaleY:                   1,
68900
68901    /**
68902     * When true, an object is rendered as flipped horizontally
68903     * @type Boolean
68904     * @default
68905     */
68906    flipX:                    false,
68907
68908    /**
68909     * When true, an object is rendered as flipped vertically
68910     * @type Boolean
68911     * @default
68912     */
68913    flipY:                    false,
68914
68915    /**
68916     * Opacity of an object
68917     * @type Number
68918     * @default
68919     */
68920    opacity:                  1,
68921
68922    /**
68923     * Angle of rotation of an object (in degrees)
68924     * @type Number
68925     * @default
68926     */
68927    angle:                    0,
68928
68929    /**
68930     * Angle of skew on x axes of an object (in degrees)
68931     * @type Number
68932     * @default
68933     */
68934    skewX:                    0,
68935
68936    /**
68937     * Angle of skew on y axes of an object (in degrees)
68938     * @type Number
68939     * @default
68940     */
68941    skewY:                    0,
68942
68943    /**
68944     * Size of object's controlling corners (in pixels)
68945     * @type Number
68946     * @default
68947     */
68948    cornerSize:               13,
68949
68950    /**
68951     * Size of object's controlling corners when touch interaction is detected
68952     * @type Number
68953     * @default
68954     */
68955    touchCornerSize:               24,
68956
68957    /**
68958     * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill)
68959     * @type Boolean
68960     * @default
68961     */
68962    transparentCorners:       true,
68963
68964    /**
68965     * Default cursor value used when hovering over this object on canvas
68966     * @type String
68967     * @default
68968     */
68969    hoverCursor:              null,
68970
68971    /**
68972     * Default cursor value used when moving this object on canvas
68973     * @type String
68974     * @default
68975     */
68976    moveCursor:               null,
68977
68978    /**
68979     * Padding between object and its controlling borders (in pixels)
68980     * @type Number
68981     * @default
68982     */
68983    padding:                  0,
68984
68985    /**
68986     * Color of controlling borders of an object (when it's active)
68987     * @type String
68988     * @default
68989     */
68990    borderColor:              'rgb(178,204,255)',
68991
68992    /**
68993     * Array specifying dash pattern of an object's borders (hasBorder must be true)
68994     * @since 1.6.2
68995     * @type Array
68996     */
68997    borderDashArray:          null,
68998
68999    /**
69000     * Color of controlling corners of an object (when it's active)
69001     * @type String
69002     * @default
69003     */
69004    cornerColor:              'rgb(178,204,255)',
69005
69006    /**
69007     * Color of controlling corners of an object (when it's active and transparentCorners false)
69008     * @since 1.6.2
69009     * @type String
69010     * @default
69011     */
69012    cornerStrokeColor:        null,
69013
69014    /**
69015     * Specify style of control, 'rect' or 'circle'
69016     * @since 1.6.2
69017     * @type String
69018     */
69019    cornerStyle:          'rect',
69020
69021    /**
69022     * Array specifying dash pattern of an object's control (hasBorder must be true)
69023     * @since 1.6.2
69024     * @type Array
69025     */
69026    cornerDashArray:          null,
69027
69028    /**
69029     * When true, this object will use center point as the origin of transformation
69030     * when being scaled via the controls.
69031     * <b>Backwards incompatibility note:</b> This property replaces "centerTransform" (Boolean).
69032     * @since 1.3.4
69033     * @type Boolean
69034     * @default
69035     */
69036    centeredScaling:          false,
69037
69038    /**
69039     * When true, this object will use center point as the origin of transformation
69040     * when being rotated via the controls.
69041     * <b>Backwards incompatibility note:</b> This property replaces "centerTransform" (Boolean).
69042     * @since 1.3.4
69043     * @type Boolean
69044     * @default
69045     */
69046    centeredRotation:         true,
69047
69048    /**
69049     * Color of object's fill
69050     * takes css colors https://www.w3.org/TR/css-color-3/
69051     * @type String
69052     * @default
69053     */
69054    fill:                     'rgb(0,0,0)',
69055
69056    /**
69057     * Fill rule used to fill an object
69058     * accepted values are nonzero, evenodd
69059     * <b>Backwards incompatibility note:</b> This property was used for setting globalCompositeOperation until v1.4.12 (use `fabric.Object#globalCompositeOperation` instead)
69060     * @type String
69061     * @default
69062     */
69063    fillRule:                 'nonzero',
69064
69065    /**
69066     * Composite rule used for canvas globalCompositeOperation
69067     * @type String
69068     * @default
69069     */
69070    globalCompositeOperation: 'source-over',
69071
69072    /**
69073     * Background color of an object.
69074     * takes css colors https://www.w3.org/TR/css-color-3/
69075     * @type String
69076     * @default
69077     */
69078    backgroundColor:          '',
69079
69080    /**
69081     * Selection Background color of an object. colored layer behind the object when it is active.
69082     * does not mix good with globalCompositeOperation methods.
69083     * @type String
69084     * @default
69085     */
69086    selectionBackgroundColor:          '',
69087
69088    /**
69089     * When defined, an object is rendered via stroke and this property specifies its color
69090     * takes css colors https://www.w3.org/TR/css-color-3/
69091     * @type String
69092     * @default
69093     */
69094    stroke:                   null,
69095
69096    /**
69097     * Width of a stroke used to render this object
69098     * @type Number
69099     * @default
69100     */
69101    strokeWidth:              1,
69102
69103    /**
69104     * Array specifying dash pattern of an object's stroke (stroke must be defined)
69105     * @type Array
69106     */
69107    strokeDashArray:          null,
69108
69109    /**
69110     * Line offset of an object's stroke
69111     * @type Number
69112     * @default
69113     */
69114    strokeDashOffset: 0,
69115
69116    /**
69117     * Line endings style of an object's stroke (one of "butt", "round", "square")
69118     * @type String
69119     * @default
69120     */
69121    strokeLineCap:            'butt',
69122
69123    /**
69124     * Corner style of an object's stroke (one of "bevel", "round", "miter")
69125     * @type String
69126     * @default
69127     */
69128    strokeLineJoin:           'miter',
69129
69130    /**
69131     * Maximum miter length (used for strokeLineJoin = "miter") of an object's stroke
69132     * @type Number
69133     * @default
69134     */
69135    strokeMiterLimit:         4,
69136
69137    /**
69138     * Shadow object representing shadow of this shape
69139     * @type fabric.Shadow
69140     * @default
69141     */
69142    shadow:                   null,
69143
69144    /**
69145     * Opacity of object's controlling borders when object is active and moving
69146     * @type Number
69147     * @default
69148     */
69149    borderOpacityWhenMoving:  0.4,
69150
69151    /**
69152     * Scale factor of object's controlling borders
69153     * bigger number will make a thicker border
69154     * border is 1, so this is basically a border thickness
69155     * since there is no way to change the border itself.
69156     * @type Number
69157     * @default
69158     */
69159    borderScaleFactor:        1,
69160
69161    /**
69162     * Minimum allowed scale value of an object
69163     * @type Number
69164     * @default
69165     */
69166    minScaleLimit:            0,
69167
69168    /**
69169     * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection).
69170     * But events still fire on it.
69171     * @type Boolean
69172     * @default
69173     */
69174    selectable:               true,
69175
69176    /**
69177     * When set to `false`, an object can not be a target of events. All events propagate through it. Introduced in v1.3.4
69178     * @type Boolean
69179     * @default
69180     */
69181    evented:                  true,
69182
69183    /**
69184     * When set to `false`, an object is not rendered on canvas
69185     * @type Boolean
69186     * @default
69187     */
69188    visible:                  true,
69189
69190    /**
69191     * When set to `false`, object's controls are not displayed and can not be used to manipulate object
69192     * @type Boolean
69193     * @default
69194     */
69195    hasControls:              true,
69196
69197    /**
69198     * When set to `false`, object's controlling borders are not rendered
69199     * @type Boolean
69200     * @default
69201     */
69202    hasBorders:               true,
69203
69204    /**
69205     * When set to `true`, objects are "found" on canvas on per-pixel basis rather than according to bounding box
69206     * @type Boolean
69207     * @default
69208     */
69209    perPixelTargetFind:       false,
69210
69211    /**
69212     * When `false`, default object's values are not included in its serialization
69213     * @type Boolean
69214     * @default
69215     */
69216    includeDefaultValues:     true,
69217
69218    /**
69219     * When `true`, object horizontal movement is locked
69220     * @type Boolean
69221     * @default
69222     */
69223    lockMovementX:            false,
69224
69225    /**
69226     * When `true`, object vertical movement is locked
69227     * @type Boolean
69228     * @default
69229     */
69230    lockMovementY:            false,
69231
69232    /**
69233     * When `true`, object rotation is locked
69234     * @type Boolean
69235     * @default
69236     */
69237    lockRotation:             false,
69238
69239    /**
69240     * When `true`, object horizontal scaling is locked
69241     * @type Boolean
69242     * @default
69243     */
69244    lockScalingX:             false,
69245
69246    /**
69247     * When `true`, object vertical scaling is locked
69248     * @type Boolean
69249     * @default
69250     */
69251    lockScalingY:             false,
69252
69253    /**
69254     * When `true`, object horizontal skewing is locked
69255     * @type Boolean
69256     * @default
69257     */
69258    lockSkewingX:             false,
69259
69260    /**
69261     * When `true`, object vertical skewing is locked
69262     * @type Boolean
69263     * @default
69264     */
69265    lockSkewingY:             false,
69266
69267    /**
69268     * When `true`, object cannot be flipped by scaling into negative values
69269     * @type Boolean
69270     * @default
69271     */
69272    lockScalingFlip:          false,
69273
69274    /**
69275     * When `true`, object is not exported in OBJECT/JSON
69276     * @since 1.6.3
69277     * @type Boolean
69278     * @default
69279     */
69280    excludeFromExport:        false,
69281
69282    /**
69283     * When `true`, object is cached on an additional canvas.
69284     * When `false`, object is not cached unless necessary ( clipPath )
69285     * default to true
69286     * @since 1.7.0
69287     * @type Boolean
69288     * @default true
69289     */
69290    objectCaching:            objectCaching,
69291
69292    /**
69293     * When `true`, object properties are checked for cache invalidation. In some particular
69294     * situation you may want this to be disabled ( spray brush, very big, groups)
69295     * or if your application does not allow you to modify properties for groups child you want
69296     * to disable it for groups.
69297     * default to false
69298     * since 1.7.0
69299     * @type Boolean
69300     * @default false
69301     */
69302    statefullCache:            false,
69303
69304    /**
69305     * When `true`, cache does not get updated during scaling. The picture will get blocky if scaled
69306     * too much and will be redrawn with correct details at the end of scaling.
69307     * this setting is performance and application dependant.
69308     * default to true
69309     * since 1.7.0
69310     * @type Boolean
69311     * @default true
69312     */
69313    noScaleCache:              true,
69314
69315    /**
69316     * When `false`, the stoke width will scale with the object.
69317     * When `true`, the stroke will always match the exact pixel size entered for stroke width.
69318     * default to false
69319     * @since 2.6.0
69320     * @type Boolean
69321     * @default false
69322     * @type Boolean
69323     * @default false
69324     */
69325    strokeUniform:              false,
69326
69327    /**
69328     * When set to `true`, object's cache will be rerendered next render call.
69329     * since 1.7.0
69330     * @type Boolean
69331     * @default true
69332     */
69333    dirty:                true,
69334
69335    /**
69336     * keeps the value of the last hovered corner during mouse move.
69337     * 0 is no corner, or 'mt', 'ml', 'mtr' etc..
69338     * It should be private, but there is no harm in using it as
69339     * a read-only property.
69340     * @type number|string|any
69341     * @default 0
69342     */
69343    __corner: 0,
69344
69345    /**
69346     * Determines if the fill or the stroke is drawn first (one of "fill" or "stroke")
69347     * @type String
69348     * @default
69349     */
69350    paintFirst:           'fill',
69351
69352    /**
69353     * When 'down', object is set to active on mousedown/touchstart
69354     * When 'up', object is set to active on mouseup/touchend
69355     * Experimental. Let's see if this breaks anything before supporting officially
69356     * @private
69357     * since 4.4.0
69358     * @type String
69359     * @default 'down'
69360     */
69361    activeOn:           'down',
69362
69363    /**
69364     * List of properties to consider when checking if state
69365     * of an object is changed (fabric.Object#hasStateChanged)
69366     * as well as for history (undo/redo) purposes
69367     * @type Array
69368     */
69369    stateProperties: (
69370      'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' +
69371      'stroke strokeWidth strokeDashArray strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit ' +
69372      'angle opacity fill globalCompositeOperation shadow visible backgroundColor ' +
69373      'skewX skewY fillRule paintFirst clipPath strokeUniform'
69374    ).split(' '),
69375
69376    /**
69377     * List of properties to consider when checking if cache needs refresh
69378     * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single
69379     * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty
69380     * and refreshed at the next render
69381     * @type Array
69382     */
69383    cacheProperties: (
69384      'fill stroke strokeWidth strokeDashArray width height paintFirst strokeUniform' +
69385      ' strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit backgroundColor clipPath'
69386    ).split(' '),
69387
69388    /**
69389     * List of properties to consider for animating colors.
69390     * @type Array
69391     */
69392    colorProperties: (
69393      'fill stroke backgroundColor'
69394    ).split(' '),
69395
69396    /**
69397     * a fabricObject that, without stroke define a clipping area with their shape. filled in black
69398     * the clipPath object gets used when the object has rendered, and the context is placed in the center
69399     * of the object cacheCanvas.
69400     * If you want 0,0 of a clipPath to align with an object center, use clipPath.originX/Y to 'center'
69401     * @type fabric.Object
69402     */
69403    clipPath: undefined,
69404
69405    /**
69406     * Meaningful ONLY when the object is used as clipPath.
69407     * if true, the clipPath will make the object clip to the outside of the clipPath
69408     * since 2.4.0
69409     * @type boolean
69410     * @default false
69411     */
69412    inverted: false,
69413
69414    /**
69415     * Meaningful ONLY when the object is used as clipPath.
69416     * if true, the clipPath will have its top and left relative to canvas, and will
69417     * not be influenced by the object transform. This will make the clipPath relative
69418     * to the canvas, but clipping just a particular object.
69419     * WARNING this is beta, this feature may change or be renamed.
69420     * since 2.4.0
69421     * @type boolean
69422     * @default false
69423     */
69424    absolutePositioned: false,
69425
69426    /**
69427     * Constructor
69428     * @param {Object} [options] Options object
69429     */
69430    initialize: function(options) {
69431      if (options) {
69432        this.setOptions(options);
69433      }
69434    },
69435
69436    /**
69437     * Create a the canvas used to keep the cached copy of the object
69438     * @private
69439     */
69440    _createCacheCanvas: function() {
69441      this._cacheProperties = {};
69442      this._cacheCanvas = fabric.util.createCanvasElement();
69443      this._cacheContext = this._cacheCanvas.getContext('2d');
69444      this._updateCacheCanvas();
69445      // if canvas gets created, is empty, so dirty.
69446      this.dirty = true;
69447    },
69448
69449    /**
69450     * Limit the cache dimensions so that X * Y do not cross fabric.perfLimitSizeTotal
69451     * and each side do not cross fabric.cacheSideLimit
69452     * those numbers are configurable so that you can get as much detail as you want
69453     * making bargain with performances.
69454     * @param {Object} dims
69455     * @param {Object} dims.width width of canvas
69456     * @param {Object} dims.height height of canvas
69457     * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache
69458     * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache
69459     * @return {Object}.width width of canvas
69460     * @return {Object}.height height of canvas
69461     * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache
69462     * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache
69463     */
69464    _limitCacheSize: function(dims) {
69465      var perfLimitSizeTotal = fabric.perfLimitSizeTotal,
69466          width = dims.width, height = dims.height,
69467          max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit;
69468      if (width <= max && height <= max && width * height <= perfLimitSizeTotal) {
69469        if (width < min) {
69470          dims.width = min;
69471        }
69472        if (height < min) {
69473          dims.height = min;
69474        }
69475        return dims;
69476      }
69477      var ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal),
69478          capValue = fabric.util.capValue,
69479          x = capValue(min, limitedDims.x, max),
69480          y = capValue(min, limitedDims.y, max);
69481      if (width > x) {
69482        dims.zoomX /= width / x;
69483        dims.width = x;
69484        dims.capped = true;
69485      }
69486      if (height > y) {
69487        dims.zoomY /= height / y;
69488        dims.height = y;
69489        dims.capped = true;
69490      }
69491      return dims;
69492    },
69493
69494    /**
69495     * Return the dimension and the zoom level needed to create a cache canvas
69496     * big enough to host the object to be cached.
69497     * @private
69498     * @return {Object}.x width of object to be cached
69499     * @return {Object}.y height of object to be cached
69500     * @return {Object}.width width of canvas
69501     * @return {Object}.height height of canvas
69502     * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache
69503     * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache
69504     */
69505    _getCacheCanvasDimensions: function() {
69506      var objectScale = this.getTotalObjectScaling(),
69507          // caculate dimensions without skewing
69508          dim = this._getTransformedDimensions(0, 0),
69509          neededX = dim.x * objectScale.scaleX / this.scaleX,
69510          neededY = dim.y * objectScale.scaleY / this.scaleY;
69511      return {
69512        // for sure this ALIASING_LIMIT is slightly creating problem
69513        // in situation in which the cache canvas gets an upper limit
69514        // also objectScale contains already scaleX and scaleY
69515        width: neededX + ALIASING_LIMIT,
69516        height: neededY + ALIASING_LIMIT,
69517        zoomX: objectScale.scaleX,
69518        zoomY: objectScale.scaleY,
69519        x: neededX,
69520        y: neededY
69521      };
69522    },
69523
69524    /**
69525     * Update width and height of the canvas for cache
69526     * returns true or false if canvas needed resize.
69527     * @private
69528     * @return {Boolean} true if the canvas has been resized
69529     */
69530    _updateCacheCanvas: function() {
69531      var targetCanvas = this.canvas;
69532      if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) {
69533        var target = targetCanvas._currentTransform.target,
69534            action = targetCanvas._currentTransform.action;
69535        if (this === target && action.slice && action.slice(0, 5) === 'scale') {
69536          return false;
69537        }
69538      }
69539      var canvas = this._cacheCanvas,
69540          dims = this._limitCacheSize(this._getCacheCanvasDimensions()),
69541          minCacheSize = fabric.minCacheSideLimit,
69542          width = dims.width, height = dims.height, drawingWidth, drawingHeight,
69543          zoomX = dims.zoomX, zoomY = dims.zoomY,
69544          dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight,
69545          zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY,
69546          shouldRedraw = dimensionsChanged || zoomChanged,
69547          additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false;
69548      if (dimensionsChanged) {
69549        var canvasWidth = this._cacheCanvas.width,
69550            canvasHeight = this._cacheCanvas.height,
69551            sizeGrowing = width > canvasWidth || height > canvasHeight,
69552            sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&
69553              canvasWidth > minCacheSize && canvasHeight > minCacheSize;
69554        shouldResizeCanvas = sizeGrowing || sizeShrinking;
69555        if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) {
69556          additionalWidth = width * 0.1;
69557          additionalHeight = height * 0.1;
69558        }
69559      }
69560      if (this instanceof fabric.Text && this.path) {
69561        shouldRedraw = true;
69562        shouldResizeCanvas = true;
69563        additionalWidth += this.getHeightOfLine(0) * this.zoomX;
69564        additionalHeight += this.getHeightOfLine(0) * this.zoomY;
69565      }
69566      if (shouldRedraw) {
69567        if (shouldResizeCanvas) {
69568          canvas.width = Math.ceil(width + additionalWidth);
69569          canvas.height = Math.ceil(height + additionalHeight);
69570        }
69571        else {
69572          this._cacheContext.setTransform(1, 0, 0, 1, 0, 0);
69573          this._cacheContext.clearRect(0, 0, canvas.width, canvas.height);
69574        }
69575        drawingWidth = dims.x / 2;
69576        drawingHeight = dims.y / 2;
69577        this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;
69578        this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;
69579        this.cacheWidth = width;
69580        this.cacheHeight = height;
69581        this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY);
69582        this._cacheContext.scale(zoomX, zoomY);
69583        this.zoomX = zoomX;
69584        this.zoomY = zoomY;
69585        return true;
69586      }
69587      return false;
69588    },
69589
69590    /**
69591     * Sets object's properties from options
69592     * @param {Object} [options] Options object
69593     */
69594    setOptions: function(options) {
69595      this._setOptions(options);
69596      this._initGradient(options.fill, 'fill');
69597      this._initGradient(options.stroke, 'stroke');
69598      this._initPattern(options.fill, 'fill');
69599      this._initPattern(options.stroke, 'stroke');
69600    },
69601
69602    /**
69603     * Transforms context when rendering an object
69604     * @param {CanvasRenderingContext2D} ctx Context
69605     */
69606    transform: function(ctx) {
69607      var needFullTransform = (this.group && !this.group._transformDone) ||
69608         (this.group && this.canvas && ctx === this.canvas.contextTop);
69609      var m = this.calcTransformMatrix(!needFullTransform);
69610      ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
69611    },
69612
69613    /**
69614     * Returns an object representation of an instance
69615     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
69616     * @return {Object} Object representation of an instance
69617     */
69618    toObject: function(propertiesToInclude) {
69619      var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,
69620
69621          object = {
69622            type:                     this.type,
69623            version:                  fabric.version,
69624            originX:                  this.originX,
69625            originY:                  this.originY,
69626            left:                     toFixed(this.left, NUM_FRACTION_DIGITS),
69627            top:                      toFixed(this.top, NUM_FRACTION_DIGITS),
69628            width:                    toFixed(this.width, NUM_FRACTION_DIGITS),
69629            height:                   toFixed(this.height, NUM_FRACTION_DIGITS),
69630            fill:                     (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill,
69631            stroke:                   (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke,
69632            strokeWidth:              toFixed(this.strokeWidth, NUM_FRACTION_DIGITS),
69633            strokeDashArray:          this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray,
69634            strokeLineCap:            this.strokeLineCap,
69635            strokeDashOffset:         this.strokeDashOffset,
69636            strokeLineJoin:           this.strokeLineJoin,
69637            strokeUniform:            this.strokeUniform,
69638            strokeMiterLimit:         toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),
69639            scaleX:                   toFixed(this.scaleX, NUM_FRACTION_DIGITS),
69640            scaleY:                   toFixed(this.scaleY, NUM_FRACTION_DIGITS),
69641            angle:                    toFixed(this.angle, NUM_FRACTION_DIGITS),
69642            flipX:                    this.flipX,
69643            flipY:                    this.flipY,
69644            opacity:                  toFixed(this.opacity, NUM_FRACTION_DIGITS),
69645            shadow:                   (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow,
69646            visible:                  this.visible,
69647            backgroundColor:          this.backgroundColor,
69648            fillRule:                 this.fillRule,
69649            paintFirst:               this.paintFirst,
69650            globalCompositeOperation: this.globalCompositeOperation,
69651            skewX:                    toFixed(this.skewX, NUM_FRACTION_DIGITS),
69652            skewY:                    toFixed(this.skewY, NUM_FRACTION_DIGITS),
69653          };
69654
69655      if (this.clipPath && !this.clipPath.excludeFromExport) {
69656        object.clipPath = this.clipPath.toObject(propertiesToInclude);
69657        object.clipPath.inverted = this.clipPath.inverted;
69658        object.clipPath.absolutePositioned = this.clipPath.absolutePositioned;
69659      }
69660
69661      fabric.util.populateWithProperties(this, object, propertiesToInclude);
69662      if (!this.includeDefaultValues) {
69663        object = this._removeDefaultValues(object);
69664      }
69665
69666      return object;
69667    },
69668
69669    /**
69670     * Returns (dataless) object representation of an instance
69671     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
69672     * @return {Object} Object representation of an instance
69673     */
69674    toDatalessObject: function(propertiesToInclude) {
69675      // will be overwritten by subclasses
69676      return this.toObject(propertiesToInclude);
69677    },
69678
69679    /**
69680     * @private
69681     * @param {Object} object
69682     */
69683    _removeDefaultValues: function(object) {
69684      var prototype = fabric.util.getKlass(object.type).prototype,
69685          stateProperties = prototype.stateProperties;
69686      stateProperties.forEach(function(prop) {
69687        if (prop === 'left' || prop === 'top') {
69688          return;
69689        }
69690        if (object[prop] === prototype[prop]) {
69691          delete object[prop];
69692        }
69693        var isArray = Object.prototype.toString.call(object[prop]) === '[object Array]' &&
69694                      Object.prototype.toString.call(prototype[prop]) === '[object Array]';
69695
69696        // basically a check for [] === []
69697        if (isArray && object[prop].length === 0 && prototype[prop].length === 0) {
69698          delete object[prop];
69699        }
69700      });
69701
69702      return object;
69703    },
69704
69705    /**
69706     * Returns a string representation of an instance
69707     * @return {String}
69708     */
69709    toString: function() {
69710      return '#<fabric.' + capitalize(this.type) + '>';
69711    },
69712
69713    /**
69714     * Return the object scale factor counting also the group scaling
69715     * @return {Object} object with scaleX and scaleY properties
69716     */
69717    getObjectScaling: function() {
69718      // if the object is a top level one, on the canvas, we go for simple aritmetic
69719      // otherwise the complex method with angles will return approximations and decimals
69720      // and will likely kill the cache when not needed
69721      // https://github.com/fabricjs/fabric.js/issues/7157
69722      if (!this.group) {
69723        return {
69724          scaleX: this.scaleX,
69725          scaleY: this.scaleY,
69726        };
69727      }
69728      // if we are inside a group total zoom calculation is complex, we defer to generic matrices
69729      var options = fabric.util.qrDecompose(this.calcTransformMatrix());
69730      return { scaleX: Math.abs(options.scaleX), scaleY: Math.abs(options.scaleY) };
69731    },
69732
69733    /**
69734     * Return the object scale factor counting also the group scaling, zoom and retina
69735     * @return {Object} object with scaleX and scaleY properties
69736     */
69737    getTotalObjectScaling: function() {
69738      var scale = this.getObjectScaling(), scaleX = scale.scaleX, scaleY = scale.scaleY;
69739      if (this.canvas) {
69740        var zoom = this.canvas.getZoom();
69741        var retina = this.canvas.getRetinaScaling();
69742        scaleX *= zoom * retina;
69743        scaleY *= zoom * retina;
69744      }
69745      return { scaleX: scaleX, scaleY: scaleY };
69746    },
69747
69748    /**
69749     * Return the object opacity counting also the group property
69750     * @return {Number}
69751     */
69752    getObjectOpacity: function() {
69753      var opacity = this.opacity;
69754      if (this.group) {
69755        opacity *= this.group.getObjectOpacity();
69756      }
69757      return opacity;
69758    },
69759
69760    /**
69761     * @private
69762     * @param {String} key
69763     * @param {*} value
69764     * @return {fabric.Object} thisArg
69765     */
69766    _set: function(key, value) {
69767      var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'),
69768          isChanged = this[key] !== value, groupNeedsUpdate = false;
69769
69770      if (shouldConstrainValue) {
69771        value = this._constrainScale(value);
69772      }
69773      if (key === 'scaleX' && value < 0) {
69774        this.flipX = !this.flipX;
69775        value *= -1;
69776      }
69777      else if (key === 'scaleY' && value < 0) {
69778        this.flipY = !this.flipY;
69779        value *= -1;
69780      }
69781      else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) {
69782        value = new fabric.Shadow(value);
69783      }
69784      else if (key === 'dirty' && this.group) {
69785        this.group.set('dirty', value);
69786      }
69787
69788      this[key] = value;
69789
69790      if (isChanged) {
69791        groupNeedsUpdate = this.group && this.group.isOnACache();
69792        if (this.cacheProperties.indexOf(key) > -1) {
69793          this.dirty = true;
69794          groupNeedsUpdate && this.group.set('dirty', true);
69795        }
69796        else if (groupNeedsUpdate && this.stateProperties.indexOf(key) > -1) {
69797          this.group.set('dirty', true);
69798        }
69799      }
69800      return this;
69801    },
69802
69803    /**
69804     * This callback function is called by the parent group of an object every
69805     * time a non-delegated property changes on the group. It is passed the key
69806     * and value as parameters. Not adding in this function's signature to avoid
69807     * Travis build error about unused variables.
69808     */
69809    setOnGroup: function() {
69810      // implemented by sub-classes, as needed.
69811    },
69812
69813    /**
69814     * Retrieves viewportTransform from Object's canvas if possible
69815     * @method getViewportTransform
69816     * @memberOf fabric.Object.prototype
69817     * @return {Array}
69818     */
69819    getViewportTransform: function() {
69820      if (this.canvas && this.canvas.viewportTransform) {
69821        return this.canvas.viewportTransform;
69822      }
69823      return fabric.iMatrix.concat();
69824    },
69825
69826    /*
69827     * @private
69828     * return if the object would be visible in rendering
69829     * @memberOf fabric.Object.prototype
69830     * @return {Boolean}
69831     */
69832    isNotVisible: function() {
69833      return this.opacity === 0 ||
69834        (!this.width && !this.height && this.strokeWidth === 0) ||
69835        !this.visible;
69836    },
69837
69838    /**
69839     * Renders an object on a specified context
69840     * @param {CanvasRenderingContext2D} ctx Context to render on
69841     */
69842    render: function(ctx) {
69843      // do not render if width/height are zeros or object is not visible
69844      if (this.isNotVisible()) {
69845        return;
69846      }
69847      if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {
69848        return;
69849      }
69850      ctx.save();
69851      this._setupCompositeOperation(ctx);
69852      this.drawSelectionBackground(ctx);
69853      this.transform(ctx);
69854      this._setOpacity(ctx);
69855      this._setShadow(ctx, this);
69856      if (this.shouldCache()) {
69857        this.renderCache();
69858        this.drawCacheOnCanvas(ctx);
69859      }
69860      else {
69861        this._removeCacheCanvas();
69862        this.dirty = false;
69863        this.drawObject(ctx);
69864        if (this.objectCaching && this.statefullCache) {
69865          this.saveState({ propertySet: 'cacheProperties' });
69866        }
69867      }
69868      ctx.restore();
69869    },
69870
69871    renderCache: function(options) {
69872      options = options || {};
69873      if (!this._cacheCanvas) {
69874        this._createCacheCanvas();
69875      }
69876      if (this.isCacheDirty()) {
69877        this.statefullCache && this.saveState({ propertySet: 'cacheProperties' });
69878        this.drawObject(this._cacheContext, options.forClipping);
69879        this.dirty = false;
69880      }
69881    },
69882
69883    /**
69884     * Remove cacheCanvas and its dimensions from the objects
69885     */
69886    _removeCacheCanvas: function() {
69887      this._cacheCanvas = null;
69888      this.cacheWidth = 0;
69889      this.cacheHeight = 0;
69890    },
69891
69892    /**
69893     * return true if the object will draw a stroke
69894     * Does not consider text styles. This is just a shortcut used at rendering time
69895     * We want it to be an approximation and be fast.
69896     * wrote to avoid extra caching, it has to return true when stroke happens,
69897     * can guess when it will not happen at 100% chance, does not matter if it misses
69898     * some use case where the stroke is invisible.
69899     * @since 3.0.0
69900     * @returns Boolean
69901     */
69902    hasStroke: function() {
69903      return this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0;
69904    },
69905
69906    /**
69907     * return true if the object will draw a fill
69908     * Does not consider text styles. This is just a shortcut used at rendering time
69909     * We want it to be an approximation and be fast.
69910     * wrote to avoid extra caching, it has to return true when fill happens,
69911     * can guess when it will not happen at 100% chance, does not matter if it misses
69912     * some use case where the fill is invisible.
69913     * @since 3.0.0
69914     * @returns Boolean
69915     */
69916    hasFill: function() {
69917      return this.fill && this.fill !== 'transparent';
69918    },
69919
69920    /**
69921     * When set to `true`, force the object to have its own cache, even if it is inside a group
69922     * it may be needed when your object behave in a particular way on the cache and always needs
69923     * its own isolated canvas to render correctly.
69924     * Created to be overridden
69925     * since 1.7.12
69926     * @returns Boolean
69927     */
69928    needsItsOwnCache: function() {
69929      if (this.paintFirst === 'stroke' &&
69930        this.hasFill() && this.hasStroke() && typeof this.shadow === 'object') {
69931        return true;
69932      }
69933      if (this.clipPath) {
69934        return true;
69935      }
69936      return false;
69937    },
69938
69939    /**
69940     * Decide if the object should cache or not. Create its own cache level
69941     * objectCaching is a global flag, wins over everything
69942     * needsItsOwnCache should be used when the object drawing method requires
69943     * a cache step. None of the fabric classes requires it.
69944     * Generally you do not cache objects in groups because the group outside is cached.
69945     * Read as: cache if is needed, or if the feature is enabled but we are not already caching.
69946     * @return {Boolean}
69947     */
69948    shouldCache: function() {
69949      this.ownCaching = this.needsItsOwnCache() || (
69950        this.objectCaching &&
69951        (!this.group || !this.group.isOnACache())
69952      );
69953      return this.ownCaching;
69954    },
69955
69956    /**
69957     * Check if this object or a child object will cast a shadow
69958     * used by Group.shouldCache to know if child has a shadow recursively
69959     * @return {Boolean}
69960     */
69961    willDrawShadow: function() {
69962      return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0);
69963    },
69964
69965    /**
69966     * Execute the drawing operation for an object clipPath
69967     * @param {CanvasRenderingContext2D} ctx Context to render on
69968     */
69969    drawClipPathOnCache: function(ctx) {
69970      var path = this.clipPath;
69971      ctx.save();
69972      // DEBUG: uncomment this line, comment the following
69973      // ctx.globalAlpha = 0.4
69974      if (path.inverted) {
69975        ctx.globalCompositeOperation = 'destination-out';
69976      }
69977      else {
69978        ctx.globalCompositeOperation = 'destination-in';
69979      }
69980      //ctx.scale(1 / 2, 1 / 2);
69981      if (path.absolutePositioned) {
69982        var m = fabric.util.invertTransform(this.calcTransformMatrix());
69983        ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
69984      }
69985      path.transform(ctx);
69986      ctx.scale(1 / path.zoomX, 1 / path.zoomY);
69987      ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY);
69988      ctx.restore();
69989    },
69990
69991    /**
69992     * Execute the drawing operation for an object on a specified context
69993     * @param {CanvasRenderingContext2D} ctx Context to render on
69994     */
69995    drawObject: function(ctx, forClipping) {
69996      var originalFill = this.fill, originalStroke = this.stroke;
69997      if (forClipping) {
69998        this.fill = 'black';
69999        this.stroke = '';
70000        this._setClippingProperties(ctx);
70001      }
70002      else {
70003        this._renderBackground(ctx);
70004      }
70005      this._render(ctx);
70006      this._drawClipPath(ctx);
70007      this.fill = originalFill;
70008      this.stroke = originalStroke;
70009    },
70010
70011    _drawClipPath: function(ctx) {
70012      var path = this.clipPath;
70013      if (!path) { return; }
70014      // needed to setup a couple of variables
70015      // path canvas gets overridden with this one.
70016      // TODO find a better solution?
70017      path.canvas = this.canvas;
70018      path.shouldCache();
70019      path._transformDone = true;
70020      path.renderCache({ forClipping: true });
70021      this.drawClipPathOnCache(ctx);
70022    },
70023
70024    /**
70025     * Paint the cached copy of the object on the target context.
70026     * @param {CanvasRenderingContext2D} ctx Context to render on
70027     */
70028    drawCacheOnCanvas: function(ctx) {
70029      ctx.scale(1 / this.zoomX, 1 / this.zoomY);
70030      ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY);
70031    },
70032
70033    /**
70034     * Check if cache is dirty
70035     * @param {Boolean} skipCanvas skip canvas checks because this object is painted
70036     * on parent canvas.
70037     */
70038    isCacheDirty: function(skipCanvas) {
70039      if (this.isNotVisible()) {
70040        return false;
70041      }
70042      if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) {
70043        // in this case the context is already cleared.
70044        return true;
70045      }
70046      else {
70047        if (this.dirty ||
70048          (this.clipPath && this.clipPath.absolutePositioned) ||
70049          (this.statefullCache && this.hasStateChanged('cacheProperties'))
70050        ) {
70051          if (this._cacheCanvas && !skipCanvas) {
70052            var width = this.cacheWidth / this.zoomX;
70053            var height = this.cacheHeight / this.zoomY;
70054            this._cacheContext.clearRect(-width / 2, -height / 2, width, height);
70055          }
70056          return true;
70057        }
70058      }
70059      return false;
70060    },
70061
70062    /**
70063     * Draws a background for the object big as its untransformed dimensions
70064     * @private
70065     * @param {CanvasRenderingContext2D} ctx Context to render on
70066     */
70067    _renderBackground: function(ctx) {
70068      if (!this.backgroundColor) {
70069        return;
70070      }
70071      var dim = this._getNonTransformedDimensions();
70072      ctx.fillStyle = this.backgroundColor;
70073
70074      ctx.fillRect(
70075        -dim.x / 2,
70076        -dim.y / 2,
70077        dim.x,
70078        dim.y
70079      );
70080      // if there is background color no other shadows
70081      // should be casted
70082      this._removeShadow(ctx);
70083    },
70084
70085    /**
70086     * @private
70087     * @param {CanvasRenderingContext2D} ctx Context to render on
70088     */
70089    _setOpacity: function(ctx) {
70090      if (this.group && !this.group._transformDone) {
70091        ctx.globalAlpha = this.getObjectOpacity();
70092      }
70093      else {
70094        ctx.globalAlpha *= this.opacity;
70095      }
70096    },
70097
70098    _setStrokeStyles: function(ctx, decl) {
70099      var stroke = decl.stroke;
70100      if (stroke) {
70101        ctx.lineWidth = decl.strokeWidth;
70102        ctx.lineCap = decl.strokeLineCap;
70103        ctx.lineDashOffset = decl.strokeDashOffset;
70104        ctx.lineJoin = decl.strokeLineJoin;
70105        ctx.miterLimit = decl.strokeMiterLimit;
70106        if (stroke.toLive) {
70107          if (stroke.gradientUnits === 'percentage' || stroke.gradientTransform || stroke.patternTransform) {
70108            // need to transform gradient in a pattern.
70109            // this is a slow process. If you are hitting this codepath, and the object
70110            // is not using caching, you should consider switching it on.
70111            // we need a canvas as big as the current object caching canvas.
70112            this._applyPatternForTransformedGradient(ctx, stroke);
70113          }
70114          else {
70115            // is a simple gradient or pattern
70116            ctx.strokeStyle = stroke.toLive(ctx, this);
70117            this._applyPatternGradientTransform(ctx, stroke);
70118          }
70119        }
70120        else {
70121          // is a color
70122          ctx.strokeStyle = decl.stroke;
70123        }
70124      }
70125    },
70126
70127    _setFillStyles: function(ctx, decl) {
70128      var fill = decl.fill;
70129      if (fill) {
70130        if (fill.toLive) {
70131          ctx.fillStyle = fill.toLive(ctx, this);
70132          this._applyPatternGradientTransform(ctx, decl.fill);
70133        }
70134        else {
70135          ctx.fillStyle = fill;
70136        }
70137      }
70138    },
70139
70140    _setClippingProperties: function(ctx) {
70141      ctx.globalAlpha = 1;
70142      ctx.strokeStyle = 'transparent';
70143      ctx.fillStyle = '#000000';
70144    },
70145
70146    /**
70147     * @private
70148     * Sets line dash
70149     * @param {CanvasRenderingContext2D} ctx Context to set the dash line on
70150     * @param {Array} dashArray array representing dashes
70151     */
70152    _setLineDash: function(ctx, dashArray) {
70153      if (!dashArray || dashArray.length === 0) {
70154        return;
70155      }
70156      // Spec requires the concatenation of two copies the dash list when the number of elements is odd
70157      if (1 & dashArray.length) {
70158        dashArray.push.apply(dashArray, dashArray);
70159      }
70160      ctx.setLineDash(dashArray);
70161    },
70162
70163    /**
70164     * Renders controls and borders for the object
70165     * @param {CanvasRenderingContext2D} ctx Context to render on
70166     * @param {Object} [styleOverride] properties to override the object style
70167     */
70168    _renderControls: function(ctx, styleOverride) {
70169      var vpt = this.getViewportTransform(),
70170          matrix = this.calcTransformMatrix(),
70171          options, drawBorders, drawControls;
70172      styleOverride = styleOverride || { };
70173      drawBorders = typeof styleOverride.hasBorders !== 'undefined' ? styleOverride.hasBorders : this.hasBorders;
70174      drawControls = typeof styleOverride.hasControls !== 'undefined' ? styleOverride.hasControls : this.hasControls;
70175      matrix = fabric.util.multiplyTransformMatrices(vpt, matrix);
70176      options = fabric.util.qrDecompose(matrix);
70177      ctx.save();
70178      ctx.translate(options.translateX, options.translateY);
70179      ctx.lineWidth = 1 * this.borderScaleFactor;
70180      if (!this.group) {
70181        ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;
70182      }
70183      ctx.rotate(degreesToRadians(options.angle));
70184      if (styleOverride.forActiveSelection || this.group) {
70185        drawBorders && this.drawBordersInGroup(ctx, options, styleOverride);
70186      }
70187      else {
70188        drawBorders && this.drawBorders(ctx, styleOverride);
70189      }
70190      drawControls && this.drawControls(ctx, styleOverride);
70191      ctx.restore();
70192    },
70193
70194    /**
70195     * @private
70196     * @param {CanvasRenderingContext2D} ctx Context to render on
70197     */
70198    _setShadow: function(ctx) {
70199      if (!this.shadow) {
70200        return;
70201      }
70202
70203      var shadow = this.shadow, canvas = this.canvas, scaling,
70204          multX = (canvas && canvas.viewportTransform[0]) || 1,
70205          multY = (canvas && canvas.viewportTransform[3]) || 1;
70206      if (shadow.nonScaling) {
70207        scaling = { scaleX: 1, scaleY: 1 };
70208      }
70209      else {
70210        scaling = this.getObjectScaling();
70211      }
70212      if (canvas && canvas._isRetinaScaling()) {
70213        multX *= fabric.devicePixelRatio;
70214        multY *= fabric.devicePixelRatio;
70215      }
70216      ctx.shadowColor = shadow.color;
70217      ctx.shadowBlur = shadow.blur * fabric.browserShadowBlurConstant *
70218        (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4;
70219      ctx.shadowOffsetX = shadow.offsetX * multX * scaling.scaleX;
70220      ctx.shadowOffsetY = shadow.offsetY * multY * scaling.scaleY;
70221    },
70222
70223    /**
70224     * @private
70225     * @param {CanvasRenderingContext2D} ctx Context to render on
70226     */
70227    _removeShadow: function(ctx) {
70228      if (!this.shadow) {
70229        return;
70230      }
70231
70232      ctx.shadowColor = '';
70233      ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;
70234    },
70235
70236    /**
70237     * @private
70238     * @param {CanvasRenderingContext2D} ctx Context to render on
70239     * @param {Object} filler fabric.Pattern or fabric.Gradient
70240     * @return {Object} offset.offsetX offset for text rendering
70241     * @return {Object} offset.offsetY offset for text rendering
70242     */
70243    _applyPatternGradientTransform: function(ctx, filler) {
70244      if (!filler || !filler.toLive) {
70245        return { offsetX: 0, offsetY: 0 };
70246      }
70247      var t = filler.gradientTransform || filler.patternTransform;
70248      var offsetX = -this.width / 2 + filler.offsetX || 0,
70249          offsetY = -this.height / 2 + filler.offsetY || 0;
70250
70251      if (filler.gradientUnits === 'percentage') {
70252        ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY);
70253      }
70254      else {
70255        ctx.transform(1, 0, 0, 1, offsetX, offsetY);
70256      }
70257      if (t) {
70258        ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]);
70259      }
70260      return { offsetX: offsetX, offsetY: offsetY };
70261    },
70262
70263    /**
70264     * @private
70265     * @param {CanvasRenderingContext2D} ctx Context to render on
70266     */
70267    _renderPaintInOrder: function(ctx) {
70268      if (this.paintFirst === 'stroke') {
70269        this._renderStroke(ctx);
70270        this._renderFill(ctx);
70271      }
70272      else {
70273        this._renderFill(ctx);
70274        this._renderStroke(ctx);
70275      }
70276    },
70277
70278    /**
70279     * @private
70280     * function that actually render something on the context.
70281     * empty here to allow Obects to work on tests to benchmark fabric functionalites
70282     * not related to rendering
70283     * @param {CanvasRenderingContext2D} ctx Context to render on
70284     */
70285    _render: function(/* ctx */) {
70286
70287    },
70288
70289    /**
70290     * @private
70291     * @param {CanvasRenderingContext2D} ctx Context to render on
70292     */
70293    _renderFill: function(ctx) {
70294      if (!this.fill) {
70295        return;
70296      }
70297
70298      ctx.save();
70299      this._setFillStyles(ctx, this);
70300      if (this.fillRule === 'evenodd') {
70301        ctx.fill('evenodd');
70302      }
70303      else {
70304        ctx.fill();
70305      }
70306      ctx.restore();
70307    },
70308
70309    /**
70310     * @private
70311     * @param {CanvasRenderingContext2D} ctx Context to render on
70312     */
70313    _renderStroke: function(ctx) {
70314      if (!this.stroke || this.strokeWidth === 0) {
70315        return;
70316      }
70317
70318      if (this.shadow && !this.shadow.affectStroke) {
70319        this._removeShadow(ctx);
70320      }
70321
70322      ctx.save();
70323      if (this.strokeUniform && this.group) {
70324        var scaling = this.getObjectScaling();
70325        ctx.scale(1 / scaling.scaleX, 1 / scaling.scaleY);
70326      }
70327      else if (this.strokeUniform) {
70328        ctx.scale(1 / this.scaleX, 1 / this.scaleY);
70329      }
70330      this._setLineDash(ctx, this.strokeDashArray);
70331      this._setStrokeStyles(ctx, this);
70332      ctx.stroke();
70333      ctx.restore();
70334    },
70335
70336    /**
70337     * This function try to patch the missing gradientTransform on canvas gradients.
70338     * transforming a context to transform the gradient, is going to transform the stroke too.
70339     * we want to transform the gradient but not the stroke operation, so we create
70340     * a transformed gradient on a pattern and then we use the pattern instead of the gradient.
70341     * this method has drwabacks: is slow, is in low resolution, needs a patch for when the size
70342     * is limited.
70343     * @private
70344     * @param {CanvasRenderingContext2D} ctx Context to render on
70345     * @param {fabric.Gradient} filler a fabric gradient instance
70346     */
70347    _applyPatternForTransformedGradient: function(ctx, filler) {
70348      var dims = this._limitCacheSize(this._getCacheCanvasDimensions()),
70349          pCanvas = fabric.util.createCanvasElement(), pCtx, retinaScaling = this.canvas.getRetinaScaling(),
70350          width = dims.x / this.scaleX / retinaScaling, height = dims.y / this.scaleY / retinaScaling;
70351      pCanvas.width = width;
70352      pCanvas.height = height;
70353      pCtx = pCanvas.getContext('2d');
70354      pCtx.beginPath(); pCtx.moveTo(0, 0); pCtx.lineTo(width, 0); pCtx.lineTo(width, height);
70355      pCtx.lineTo(0, height); pCtx.closePath();
70356      pCtx.translate(width / 2, height / 2);
70357      pCtx.scale(
70358        dims.zoomX / this.scaleX / retinaScaling,
70359        dims.zoomY / this.scaleY / retinaScaling
70360      );
70361      this._applyPatternGradientTransform(pCtx, filler);
70362      pCtx.fillStyle = filler.toLive(ctx);
70363      pCtx.fill();
70364      ctx.translate(-this.width / 2 - this.strokeWidth / 2, -this.height / 2 - this.strokeWidth / 2);
70365      ctx.scale(
70366        retinaScaling * this.scaleX / dims.zoomX,
70367        retinaScaling * this.scaleY / dims.zoomY
70368      );
70369      ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat');
70370    },
70371
70372    /**
70373     * This function is an helper for svg import. it returns the center of the object in the svg
70374     * untransformed coordinates
70375     * @private
70376     * @return {Object} center point from element coordinates
70377     */
70378    _findCenterFromElement: function() {
70379      return { x: this.left + this.width / 2, y: this.top + this.height / 2 };
70380    },
70381
70382    /**
70383     * This function is an helper for svg import. it decompose the transformMatrix
70384     * and assign properties to object.
70385     * untransformed coordinates
70386     * @private
70387     * @chainable
70388     */
70389    _assignTransformMatrixProps: function() {
70390      if (this.transformMatrix) {
70391        var options = fabric.util.qrDecompose(this.transformMatrix);
70392        this.flipX = false;
70393        this.flipY = false;
70394        this.set('scaleX', options.scaleX);
70395        this.set('scaleY', options.scaleY);
70396        this.angle = options.angle;
70397        this.skewX = options.skewX;
70398        this.skewY = 0;
70399      }
70400    },
70401
70402    /**
70403     * This function is an helper for svg import. it removes the transform matrix
70404     * and set to object properties that fabricjs can handle
70405     * @private
70406     * @param {Object} preserveAspectRatioOptions
70407     * @return {thisArg}
70408     */
70409    _removeTransformMatrix: function(preserveAspectRatioOptions) {
70410      var center = this._findCenterFromElement();
70411      if (this.transformMatrix) {
70412        this._assignTransformMatrixProps();
70413        center = fabric.util.transformPoint(center, this.transformMatrix);
70414      }
70415      this.transformMatrix = null;
70416      if (preserveAspectRatioOptions) {
70417        this.scaleX *= preserveAspectRatioOptions.scaleX;
70418        this.scaleY *= preserveAspectRatioOptions.scaleY;
70419        this.cropX = preserveAspectRatioOptions.cropX;
70420        this.cropY = preserveAspectRatioOptions.cropY;
70421        center.x += preserveAspectRatioOptions.offsetLeft;
70422        center.y += preserveAspectRatioOptions.offsetTop;
70423        this.width = preserveAspectRatioOptions.width;
70424        this.height = preserveAspectRatioOptions.height;
70425      }
70426      this.setPositionByOrigin(center, 'center', 'center');
70427    },
70428
70429    /**
70430     * Clones an instance, using a callback method will work for every object.
70431     * @param {Function} callback Callback is invoked with a clone as a first argument
70432     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
70433     */
70434    clone: function(callback, propertiesToInclude) {
70435      var objectForm = this.toObject(propertiesToInclude);
70436      if (this.constructor.fromObject) {
70437        this.constructor.fromObject(objectForm, callback);
70438      }
70439      else {
70440        fabric.Object._fromObject('Object', objectForm, callback);
70441      }
70442    },
70443
70444    /**
70445     * Creates an instance of fabric.Image out of an object
70446     * makes use of toCanvasElement.
70447     * Once this method was based on toDataUrl and loadImage, so it also had a quality
70448     * and format option. toCanvasElement is faster and produce no loss of quality.
70449     * If you need to get a real Jpeg or Png from an object, using toDataURL is the right way to do it.
70450     * toCanvasElement and then toBlob from the obtained canvas is also a good option.
70451     * This method is sync now, but still support the callback because we did not want to break.
70452     * When fabricJS 5.0 will be planned, this will probably be changed to not have a callback.
70453     * @param {Function} callback callback, invoked with an instance as a first argument
70454     * @param {Object} [options] for clone as image, passed to toDataURL
70455     * @param {Number} [options.multiplier=1] Multiplier to scale by
70456     * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14
70457     * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14
70458     * @param {Number} [options.width] Cropping width. Introduced in v1.2.14
70459     * @param {Number} [options.height] Cropping height. Introduced in v1.2.14
70460     * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4
70461     * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4
70462     * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2
70463     * @return {fabric.Object} thisArg
70464     */
70465    cloneAsImage: function(callback, options) {
70466      var canvasEl = this.toCanvasElement(options);
70467      if (callback) {
70468        callback(new fabric.Image(canvasEl));
70469      }
70470      return this;
70471    },
70472
70473    /**
70474     * Converts an object into a HTMLCanvas element
70475     * @param {Object} options Options object
70476     * @param {Number} [options.multiplier=1] Multiplier to scale by
70477     * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14
70478     * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14
70479     * @param {Number} [options.width] Cropping width. Introduced in v1.2.14
70480     * @param {Number} [options.height] Cropping height. Introduced in v1.2.14
70481     * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4
70482     * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4
70483     * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2
70484     * @return {HTMLCanvasElement} Returns DOM element <canvas> with the fabric.Object
70485     */
70486    toCanvasElement: function(options) {
70487      options || (options = { });
70488
70489      var utils = fabric.util, origParams = utils.saveObjectTransform(this),
70490          originalGroup = this.group,
70491          originalShadow = this.shadow, abs = Math.abs,
70492          multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? fabric.devicePixelRatio : 1);
70493      delete this.group;
70494      if (options.withoutTransform) {
70495        utils.resetObjectTransform(this);
70496      }
70497      if (options.withoutShadow) {
70498        this.shadow = null;
70499      }
70500
70501      var el = fabric.util.createCanvasElement(),
70502          // skip canvas zoom and calculate with setCoords now.
70503          boundingRect = this.getBoundingRect(true, true),
70504          shadow = this.shadow, scaling,
70505          shadowOffset = { x: 0, y: 0 }, shadowBlur,
70506          width, height;
70507
70508      if (shadow) {
70509        shadowBlur = shadow.blur;
70510        if (shadow.nonScaling) {
70511          scaling = { scaleX: 1, scaleY: 1 };
70512        }
70513        else {
70514          scaling = this.getObjectScaling();
70515        }
70516        // consider non scaling shadow.
70517        shadowOffset.x = 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * (abs(scaling.scaleX));
70518        shadowOffset.y = 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * (abs(scaling.scaleY));
70519      }
70520      width = boundingRect.width + shadowOffset.x;
70521      height = boundingRect.height + shadowOffset.y;
70522      // if the current width/height is not an integer
70523      // we need to make it so.
70524      el.width = Math.ceil(width);
70525      el.height = Math.ceil(height);
70526      var canvas = new fabric.StaticCanvas(el, {
70527        enableRetinaScaling: false,
70528        renderOnAddRemove: false,
70529        skipOffscreen: false,
70530      });
70531      if (options.format === 'jpeg') {
70532        canvas.backgroundColor = '#fff';
70533      }
70534      this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), 'center', 'center');
70535
70536      var originalCanvas = this.canvas;
70537      canvas.add(this);
70538      var canvasEl = canvas.toCanvasElement(multiplier || 1, options);
70539      this.shadow = originalShadow;
70540      this.set('canvas', originalCanvas);
70541      if (originalGroup) {
70542        this.group = originalGroup;
70543      }
70544      this.set(origParams).setCoords();
70545      // canvas.dispose will call image.dispose that will nullify the elements
70546      // since this canvas is a simple element for the process, we remove references
70547      // to objects in this way in order to avoid object trashing.
70548      canvas._objects = [];
70549      canvas.dispose();
70550      canvas = null;
70551
70552      return canvasEl;
70553    },
70554
70555    /**
70556     * Converts an object into a data-url-like string
70557     * @param {Object} options Options object
70558     * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png"
70559     * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.
70560     * @param {Number} [options.multiplier=1] Multiplier to scale by
70561     * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14
70562     * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14
70563     * @param {Number} [options.width] Cropping width. Introduced in v1.2.14
70564     * @param {Number} [options.height] Cropping height. Introduced in v1.2.14
70565     * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4
70566     * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4
70567     * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2
70568     * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format
70569     */
70570    toDataURL: function(options) {
70571      options || (options = { });
70572      return fabric.util.toDataURL(this.toCanvasElement(options), options.format || 'png', options.quality || 1);
70573    },
70574
70575    /**
70576     * Returns true if specified type is identical to the type of an instance
70577     * @param {String} type Type to check against
70578     * @return {Boolean}
70579     */
70580    isType: function(type) {
70581      return this.type === type;
70582    },
70583
70584    /**
70585     * Returns complexity of an instance
70586     * @return {Number} complexity of this instance (is 1 unless subclassed)
70587     */
70588    complexity: function() {
70589      return 1;
70590    },
70591
70592    /**
70593     * Returns a JSON representation of an instance
70594     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
70595     * @return {Object} JSON
70596     */
70597    toJSON: function(propertiesToInclude) {
70598      // delegate, not alias
70599      return this.toObject(propertiesToInclude);
70600    },
70601
70602    /**
70603     * Sets "angle" of an instance with centered rotation
70604     * @param {Number} angle Angle value (in degrees)
70605     * @return {fabric.Object} thisArg
70606     * @chainable
70607     */
70608    rotate: function(angle) {
70609      var shouldCenterOrigin = (this.originX !== 'center' || this.originY !== 'center') && this.centeredRotation;
70610
70611      if (shouldCenterOrigin) {
70612        this._setOriginToCenter();
70613      }
70614
70615      this.set('angle', angle);
70616
70617      if (shouldCenterOrigin) {
70618        this._resetOrigin();
70619      }
70620
70621      return this;
70622    },
70623
70624    /**
70625     * Centers object horizontally on canvas to which it was added last.
70626     * You might need to call `setCoords` on an object after centering, to update controls area.
70627     * @return {fabric.Object} thisArg
70628     * @chainable
70629     */
70630    centerH: function () {
70631      this.canvas && this.canvas.centerObjectH(this);
70632      return this;
70633    },
70634
70635    /**
70636     * Centers object horizontally on current viewport of canvas to which it was added last.
70637     * You might need to call `setCoords` on an object after centering, to update controls area.
70638     * @return {fabric.Object} thisArg
70639     * @chainable
70640     */
70641    viewportCenterH: function () {
70642      this.canvas && this.canvas.viewportCenterObjectH(this);
70643      return this;
70644    },
70645
70646    /**
70647     * Centers object vertically on canvas to which it was added last.
70648     * You might need to call `setCoords` on an object after centering, to update controls area.
70649     * @return {fabric.Object} thisArg
70650     * @chainable
70651     */
70652    centerV: function () {
70653      this.canvas && this.canvas.centerObjectV(this);
70654      return this;
70655    },
70656
70657    /**
70658     * Centers object vertically on current viewport of canvas to which it was added last.
70659     * You might need to call `setCoords` on an object after centering, to update controls area.
70660     * @return {fabric.Object} thisArg
70661     * @chainable
70662     */
70663    viewportCenterV: function () {
70664      this.canvas && this.canvas.viewportCenterObjectV(this);
70665      return this;
70666    },
70667
70668    /**
70669     * Centers object vertically and horizontally on canvas to which is was added last
70670     * You might need to call `setCoords` on an object after centering, to update controls area.
70671     * @return {fabric.Object} thisArg
70672     * @chainable
70673     */
70674    center: function () {
70675      this.canvas && this.canvas.centerObject(this);
70676      return this;
70677    },
70678
70679    /**
70680     * Centers object on current viewport of canvas to which it was added last.
70681     * You might need to call `setCoords` on an object after centering, to update controls area.
70682     * @return {fabric.Object} thisArg
70683     * @chainable
70684     */
70685    viewportCenter: function () {
70686      this.canvas && this.canvas.viewportCenterObject(this);
70687      return this;
70688    },
70689
70690    /**
70691     * Returns coordinates of a pointer relative to an object
70692     * @param {Event} e Event to operate upon
70693     * @param {Object} [pointer] Pointer to operate upon (instead of event)
70694     * @return {Object} Coordinates of a pointer (x, y)
70695     */
70696    getLocalPointer: function(e, pointer) {
70697      pointer = pointer || this.canvas.getPointer(e);
70698      var pClicked = new fabric.Point(pointer.x, pointer.y),
70699          objectLeftTop = this._getLeftTopCoords();
70700      if (this.angle) {
70701        pClicked = fabric.util.rotatePoint(
70702          pClicked, objectLeftTop, degreesToRadians(-this.angle));
70703      }
70704      return {
70705        x: pClicked.x - objectLeftTop.x,
70706        y: pClicked.y - objectLeftTop.y
70707      };
70708    },
70709
70710    /**
70711     * Sets canvas globalCompositeOperation for specific object
70712     * custom composition operation for the particular object can be specified using globalCompositeOperation property
70713     * @param {CanvasRenderingContext2D} ctx Rendering canvas context
70714     */
70715    _setupCompositeOperation: function (ctx) {
70716      if (this.globalCompositeOperation) {
70717        ctx.globalCompositeOperation = this.globalCompositeOperation;
70718      }
70719    }
70720  });
70721
70722  fabric.util.createAccessors && fabric.util.createAccessors(fabric.Object);
70723
70724  extend(fabric.Object.prototype, fabric.Observable);
70725
70726  /**
70727   * Defines the number of fraction digits to use when serializing object values.
70728   * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.
70729   * @static
70730   * @memberOf fabric.Object
70731   * @constant
70732   * @type Number
70733   */
70734  fabric.Object.NUM_FRACTION_DIGITS = 2;
70735
70736  fabric.Object._fromObject = function(className, object, callback, extraParam) {
70737    var klass = fabric[className];
70738    object = clone(object, true);
70739    fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) {
70740      if (typeof patterns[0] !== 'undefined') {
70741        object.fill = patterns[0];
70742      }
70743      if (typeof patterns[1] !== 'undefined') {
70744        object.stroke = patterns[1];
70745      }
70746      fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {
70747        object.clipPath = enlivedProps[0];
70748        var instance = extraParam ? new klass(object[extraParam], object) : new klass(object);
70749        callback && callback(instance);
70750      });
70751    });
70752  };
70753
70754  /**
70755   * Unique id used internally when creating SVG elements
70756   * @static
70757   * @memberOf fabric.Object
70758   * @type Number
70759   */
70760  fabric.Object.__uid = 0;
70761})( true ? exports : 
70761this
vendor: 77,644 bytes, lines 70761-73065
70761);
70762
70763
70764(function() {
70765
70766  var degreesToRadians = fabric.util.degreesToRadians,
70767      originXOffset = {
70768        left: -0.5,
70769        center: 0,
70770        right: 0.5
70771      },
70772      originYOffset = {
70773        top: -0.5,
70774        center: 0,
70775        bottom: 0.5
70776      };
70777
70778  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {
70779
70780    /**
70781     * Translates the coordinates from a set of origin to another (based on the object's dimensions)
70782     * @param {fabric.Point} point The point which corresponds to the originX and originY params
70783     * @param {String} fromOriginX Horizontal origin: 'left', 'center' or 'right'
70784     * @param {String} fromOriginY Vertical origin: 'top', 'center' or 'bottom'
70785     * @param {String} toOriginX Horizontal origin: 'left', 'center' or 'right'
70786     * @param {String} toOriginY Vertical origin: 'top', 'center' or 'bottom'
70787     * @return {fabric.Point}
70788     */
70789    translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) {
70790      var x = point.x,
70791          y = point.y,
70792          offsetX, offsetY, dim;
70793
70794      if (typeof fromOriginX === 'string') {
70795        fromOriginX = originXOffset[fromOriginX];
70796      }
70797      else {
70798        fromOriginX -= 0.5;
70799      }
70800
70801      if (typeof toOriginX === 'string') {
70802        toOriginX = originXOffset[toOriginX];
70803      }
70804      else {
70805        toOriginX -= 0.5;
70806      }
70807
70808      offsetX = toOriginX - fromOriginX;
70809
70810      if (typeof fromOriginY === 'string') {
70811        fromOriginY = originYOffset[fromOriginY];
70812      }
70813      else {
70814        fromOriginY -= 0.5;
70815      }
70816
70817      if (typeof toOriginY === 'string') {
70818        toOriginY = originYOffset[toOriginY];
70819      }
70820      else {
70821        toOriginY -= 0.5;
70822      }
70823
70824      offsetY = toOriginY - fromOriginY;
70825
70826      if (offsetX || offsetY) {
70827        dim = this._getTransformedDimensions();
70828        x = point.x + offsetX * dim.x;
70829        y = point.y + offsetY * dim.y;
70830      }
70831
70832      return new fabric.Point(x, y);
70833    },
70834
70835    /**
70836     * Translates the coordinates from origin to center coordinates (based on the object's dimensions)
70837     * @param {fabric.Point} point The point which corresponds to the originX and originY params
70838     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'
70839     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'
70840     * @return {fabric.Point}
70841     */
70842    translateToCenterPoint: function(point, originX, originY) {
70843      var p = this.translateToGivenOrigin(point, originX, originY, 'center', 'center');
70844      if (this.angle) {
70845        return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle));
70846      }
70847      return p;
70848    },
70849
70850    /**
70851     * Translates the coordinates from center to origin coordinates (based on the object's dimensions)
70852     * @param {fabric.Point} center The point which corresponds to center of the object
70853     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'
70854     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'
70855     * @return {fabric.Point}
70856     */
70857    translateToOriginPoint: function(center, originX, originY) {
70858      var p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);
70859      if (this.angle) {
70860        return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle));
70861      }
70862      return p;
70863    },
70864
70865    /**
70866     * Returns the real center coordinates of the object
70867     * @return {fabric.Point}
70868     */
70869    getCenterPoint: function() {
70870      var leftTop = new fabric.Point(this.left, this.top);
70871      return this.translateToCenterPoint(leftTop, this.originX, this.originY);
70872    },
70873
70874    /**
70875     * Returns the coordinates of the object based on center coordinates
70876     * @param {fabric.Point} point The point which corresponds to the originX and originY params
70877     * @return {fabric.Point}
70878     */
70879    // getOriginPoint: function(center) {
70880    //   return this.translateToOriginPoint(center, this.originX, this.originY);
70881    // },
70882
70883    /**
70884     * Returns the coordinates of the object as if it has a different origin
70885     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'
70886     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'
70887     * @return {fabric.Point}
70888     */
70889    getPointByOrigin: function(originX, originY) {
70890      var center = this.getCenterPoint();
70891      return this.translateToOriginPoint(center, originX, originY);
70892    },
70893
70894    /**
70895     * Returns the point in local coordinates
70896     * @param {fabric.Point} point The point relative to the global coordinate system
70897     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'
70898     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'
70899     * @return {fabric.Point}
70900     */
70901    toLocalPoint: function(point, originX, originY) {
70902      var center = this.getCenterPoint(),
70903          p, p2;
70904
70905      if (typeof originX !== 'undefined' && typeof originY !== 'undefined' ) {
70906        p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);
70907      }
70908      else {
70909        p = new fabric.Point(this.left, this.top);
70910      }
70911
70912      p2 = new fabric.Point(point.x, point.y);
70913      if (this.angle) {
70914        p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle));
70915      }
70916      return p2.subtractEquals(p);
70917    },
70918
70919    /**
70920     * Returns the point in global coordinates
70921     * @param {fabric.Point} The point relative to the local coordinate system
70922     * @return {fabric.Point}
70923     */
70924    // toGlobalPoint: function(point) {
70925    //   return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top));
70926    // },
70927
70928    /**
70929     * Sets the position of the object taking into consideration the object's origin
70930     * @param {fabric.Point} pos The new position of the object
70931     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'
70932     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'
70933     * @return {void}
70934     */
70935    setPositionByOrigin: function(pos, originX, originY) {
70936      var center = this.translateToCenterPoint(pos, originX, originY),
70937          position = this.translateToOriginPoint(center, this.originX, this.originY);
70938      this.set('left', position.x);
70939      this.set('top', position.y);
70940    },
70941
70942    /**
70943     * @param {String} to One of 'left', 'center', 'right'
70944     */
70945    adjustPosition: function(to) {
70946      var angle = degreesToRadians(this.angle),
70947          hypotFull = this.getScaledWidth(),
70948          xFull = fabric.util.cos(angle) * hypotFull,
70949          yFull = fabric.util.sin(angle) * hypotFull,
70950          offsetFrom, offsetTo;
70951
70952      //TODO: this function does not consider mixed situation like top, center.
70953      if (typeof this.originX === 'string') {
70954        offsetFrom = originXOffset[this.originX];
70955      }
70956      else {
70957        offsetFrom = this.originX - 0.5;
70958      }
70959      if (typeof to === 'string') {
70960        offsetTo = originXOffset[to];
70961      }
70962      else {
70963        offsetTo = to - 0.5;
70964      }
70965      this.left += xFull * (offsetTo - offsetFrom);
70966      this.top += yFull * (offsetTo - offsetFrom);
70967      this.setCoords();
70968      this.originX = to;
70969    },
70970
70971    /**
70972     * Sets the origin/position of the object to it's center point
70973     * @private
70974     * @return {void}
70975     */
70976    _setOriginToCenter: function() {
70977      this._originalOriginX = this.originX;
70978      this._originalOriginY = this.originY;
70979
70980      var center = this.getCenterPoint();
70981
70982      this.originX = 'center';
70983      this.originY = 'center';
70984
70985      this.left = center.x;
70986      this.top = center.y;
70987    },
70988
70989    /**
70990     * Resets the origin/position of the object to it's original origin
70991     * @private
70992     * @return {void}
70993     */
70994    _resetOrigin: function() {
70995      var originPoint = this.translateToOriginPoint(
70996        this.getCenterPoint(),
70997        this._originalOriginX,
70998        this._originalOriginY);
70999
71000      this.originX = this._originalOriginX;
71001      this.originY = this._originalOriginY;
71002
71003      this.left = originPoint.x;
71004      this.top = originPoint.y;
71005
71006      this._originalOriginX = null;
71007      this._originalOriginY = null;
71008    },
71009
71010    /**
71011     * @private
71012     */
71013    _getLeftTopCoords: function() {
71014      return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top');
71015    },
71016  });
71017
71018})();
71019
71020
71021(function() {
71022
71023  function arrayFromCoords(coords) {
71024    return [
71025      new fabric.Point(coords.tl.x, coords.tl.y),
71026      new fabric.Point(coords.tr.x, coords.tr.y),
71027      new fabric.Point(coords.br.x, coords.br.y),
71028      new fabric.Point(coords.bl.x, coords.bl.y)
71029    ];
71030  }
71031
71032  var util = fabric.util,
71033      degreesToRadians = util.degreesToRadians,
71034      multiplyMatrices = util.multiplyTransformMatrices,
71035      transformPoint = util.transformPoint;
71036
71037  util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {
71038
71039    /**
71040     * Describe object's corner position in canvas element coordinates.
71041     * properties are depending on control keys and padding the main controls.
71042     * each property is an object with x, y and corner.
71043     * The `corner` property contains in a similar manner the 4 points of the
71044     * interactive area of the corner.
71045     * The coordinates depends from the controls positionHandler and are used
71046     * to draw and locate controls
71047     * @memberOf fabric.Object.prototype
71048     */
71049    oCoords: null,
71050
71051    /**
71052     * Describe object's corner position in canvas object absolute coordinates
71053     * properties are tl,tr,bl,br and describe the four main corner.
71054     * each property is an object with x, y, instance of Fabric.Point.
71055     * The coordinates depends from this properties: width, height, scaleX, scaleY
71056     * skewX, skewY, angle, strokeWidth, top, left.
71057     * Those coordinates are useful to understand where an object is. They get updated
71058     * with oCoords but they do not need to be updated when zoom or panning change.
71059     * The coordinates get updated with @method setCoords.
71060     * You can calculate them without updating with @method calcACoords();
71061     * @memberOf fabric.Object.prototype
71062     */
71063    aCoords: null,
71064
71065    /**
71066     * Describe object's corner position in canvas element coordinates.
71067     * includes padding. Used of object detection.
71068     * set and refreshed with setCoords and calcCoords.
71069     * @memberOf fabric.Object.prototype
71070     */
71071    lineCoords: null,
71072
71073    /**
71074     * storage for object transform matrix
71075     */
71076    ownMatrixCache: null,
71077
71078    /**
71079     * storage for object full transform matrix
71080     */
71081    matrixCache: null,
71082
71083    /**
71084     * custom controls interface
71085     * controls are added by default_controls.js
71086     */
71087    controls: { },
71088
71089    /**
71090     * return correct set of coordinates for intersection
71091     * this will return either aCoords or lineCoords.
71092     * @param {Boolean} absolute will return aCoords if true or lineCoords
71093     * @return {Object} {tl, tr, br, bl} points
71094     */
71095    _getCoords: function(absolute, calculate) {
71096      if (calculate) {
71097        return (absolute ? this.calcACoords() : this.calcLineCoords());
71098      }
71099      if (!this.aCoords || !this.lineCoords) {
71100        this.setCoords(true);
71101      }
71102      return (absolute ? this.aCoords : this.lineCoords);
71103    },
71104
71105    /**
71106     * return correct set of coordinates for intersection
71107     * this will return either aCoords or lineCoords.
71108     * The coords are returned in an array.
71109     * @return {Array} [tl, tr, br, bl] of points
71110     */
71111    getCoords: function(absolute, calculate) {
71112      return arrayFromCoords(this._getCoords(absolute, calculate));
71113    },
71114
71115    /**
71116     * Checks if object intersects with an area formed by 2 points
71117     * @param {Object} pointTL top-left point of area
71118     * @param {Object} pointBR bottom-right point of area
71119     * @param {Boolean} [absolute] use coordinates without viewportTransform
71120     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
71121     * @return {Boolean} true if object intersects with an area formed by 2 points
71122     */
71123    intersectsWithRect: function(pointTL, pointBR, absolute, calculate) {
71124      var coords = this.getCoords(absolute, calculate),
71125          intersection = fabric.Intersection.intersectPolygonRectangle(
71126            coords,
71127            pointTL,
71128            pointBR
71129          );
71130      return intersection.status === 'Intersection';
71131    },
71132
71133    /**
71134     * Checks if object intersects with another object
71135     * @param {Object} other Object to test
71136     * @param {Boolean} [absolute] use coordinates without viewportTransform
71137     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
71138     * @return {Boolean} true if object intersects with another object
71139     */
71140    intersectsWithObject: function(other, absolute, calculate) {
71141      var intersection = fabric.Intersection.intersectPolygonPolygon(
71142        this.getCoords(absolute, calculate),
71143        other.getCoords(absolute, calculate)
71144      );
71145
71146      return intersection.status === 'Intersection'
71147        || other.isContainedWithinObject(this, absolute, calculate)
71148        || this.isContainedWithinObject(other, absolute, calculate);
71149    },
71150
71151    /**
71152     * Checks if object is fully contained within area of another object
71153     * @param {Object} other Object to test
71154     * @param {Boolean} [absolute] use coordinates without viewportTransform
71155     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
71156     * @return {Boolean} true if object is fully contained within area of another object
71157     */
71158    isContainedWithinObject: function(other, absolute, calculate) {
71159      var points = this.getCoords(absolute, calculate),
71160          otherCoords = absolute ? other.aCoords : other.lineCoords,
71161          i = 0, lines = other._getImageLines(otherCoords);
71162      for (; i < 4; i++) {
71163        if (!other.containsPoint(points[i], lines)) {
71164          return false;
71165        }
71166      }
71167      return true;
71168    },
71169
71170    /**
71171     * Checks if object is fully contained within area formed by 2 points
71172     * @param {Object} pointTL top-left point of area
71173     * @param {Object} pointBR bottom-right point of area
71174     * @param {Boolean} [absolute] use coordinates without viewportTransform
71175     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
71176     * @return {Boolean} true if object is fully contained within area formed by 2 points
71177     */
71178    isContainedWithinRect: function(pointTL, pointBR, absolute, calculate) {
71179      var boundingRect = this.getBoundingRect(absolute, calculate);
71180
71181      return (
71182        boundingRect.left >= pointTL.x &&
71183        boundingRect.left + boundingRect.width <= pointBR.x &&
71184        boundingRect.top >= pointTL.y &&
71185        boundingRect.top + boundingRect.height <= pointBR.y
71186      );
71187    },
71188
71189    /**
71190     * Checks if point is inside the object
71191     * @param {fabric.Point} point Point to check against
71192     * @param {Object} [lines] object returned from @method _getImageLines
71193     * @param {Boolean} [absolute] use coordinates without viewportTransform
71194     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
71195     * @return {Boolean} true if point is inside the object
71196     */
71197    containsPoint: function(point, lines, absolute, calculate) {
71198      var coords = this._getCoords(absolute, calculate),
71199          lines = lines || this._getImageLines(coords),
71200          xPoints = this._findCrossPoints(point, lines);
71201      // if xPoints is odd then point is inside the object
71202      return (xPoints !== 0 && xPoints % 2 === 1);
71203    },
71204
71205    /**
71206     * Checks if object is contained within the canvas with current viewportTransform
71207     * the check is done stopping at first point that appears on screen
71208     * @param {Boolean} [calculate] use coordinates of current position instead of .aCoords
71209     * @return {Boolean} true if object is fully or partially contained within canvas
71210     */
71211    isOnScreen: function(calculate) {
71212      if (!this.canvas) {
71213        return false;
71214      }
71215      var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;
71216      var points = this.getCoords(true, calculate);
71217      // if some point is on screen, the object is on screen.
71218      if (points.some(function(point) {
71219        return point.x <= pointBR.x && point.x >= pointTL.x &&
71220        point.y <= pointBR.y && point.y >= pointTL.y;
71221      })) {
71222        return true;
71223      }
71224      // no points on screen, check intersection with absolute coordinates
71225      if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {
71226        return true;
71227      }
71228      return this._containsCenterOfCanvas(pointTL, pointBR, calculate);
71229    },
71230
71231    /**
71232     * Checks if the object contains the midpoint between canvas extremities
71233     * Does not make sense outside the context of isOnScreen and isPartiallyOnScreen
71234     * @private
71235     * @param {Fabric.Point} pointTL Top Left point
71236     * @param {Fabric.Point} pointBR Top Right point
71237     * @param {Boolean} calculate use coordinates of current position instead of .oCoords
71238     * @return {Boolean} true if the object contains the point
71239     */
71240    _containsCenterOfCanvas: function(pointTL, pointBR, calculate) {
71241      // worst case scenario the object is so big that contains the screen
71242      var centerPoint = { x: (pointTL.x + pointBR.x) / 2, y: (pointTL.y + pointBR.y) / 2 };
71243      if (this.containsPoint(centerPoint, null, true, calculate)) {
71244        return true;
71245      }
71246      return false;
71247    },
71248
71249    /**
71250     * Checks if object is partially contained within the canvas with current viewportTransform
71251     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
71252     * @return {Boolean} true if object is partially contained within canvas
71253     */
71254    isPartiallyOnScreen: function(calculate) {
71255      if (!this.canvas) {
71256        return false;
71257      }
71258      var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;
71259      if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {
71260        return true;
71261      }
71262      var allPointsAreOutside = this.getCoords(true, calculate).every(function(point) {
71263        return (point.x >= pointBR.x || point.x <= pointTL.x) &&
71264        (point.y >= pointBR.y || point.y <= pointTL.y);
71265      });
71266      return allPointsAreOutside && this._containsCenterOfCanvas(pointTL, pointBR, calculate);
71267    },
71268
71269    /**
71270     * Method that returns an object with the object edges in it, given the coordinates of the corners
71271     * @private
71272     * @param {Object} oCoords Coordinates of the object corners
71273     */
71274    _getImageLines: function(oCoords) {
71275
71276      var lines = {
71277        topline: {
71278          o: oCoords.tl,
71279          d: oCoords.tr
71280        },
71281        rightline: {
71282          o: oCoords.tr,
71283          d: oCoords.br
71284        },
71285        bottomline: {
71286          o: oCoords.br,
71287          d: oCoords.bl
71288        },
71289        leftline: {
71290          o: oCoords.bl,
71291          d: oCoords.tl
71292        }
71293      };
71294
71295      // // debugging
71296      // if (this.canvas.contextTop) {
71297      //   this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);
71298      //   this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);
71299      //
71300      //   this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);
71301      //   this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);
71302      //
71303      //   this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);
71304      //   this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);
71305      //
71306      //   this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);
71307      //   this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);
71308      // }
71309
71310      return lines;
71311    },
71312
71313    /**
71314     * Helper method to determine how many cross points are between the 4 object edges
71315     * and the horizontal line determined by a point on canvas
71316     * @private
71317     * @param {fabric.Point} point Point to check
71318     * @param {Object} lines Coordinates of the object being evaluated
71319     */
71320    // remove yi, not used but left code here just in case.
71321    _findCrossPoints: function(point, lines) {
71322      var b1, b2, a1, a2, xi, // yi,
71323          xcount = 0,
71324          iLine;
71325
71326      for (var lineKey in lines) {
71327        iLine = lines[lineKey];
71328        // optimisation 1: line below point. no cross
71329        if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) {
71330          continue;
71331        }
71332        // optimisation 2: line above point. no cross
71333        if ((iLine.o.y >= point.y) && (iLine.d.y >= point.y)) {
71334          continue;
71335        }
71336        // optimisation 3: vertical line case
71337        if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) {
71338          xi = iLine.o.x;
71339          // yi = point.y;
71340        }
71341        // calculate the intersection point
71342        else {
71343          b1 = 0;
71344          b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x);
71345          a1 = point.y - b1 * point.x;
71346          a2 = iLine.o.y - b2 * iLine.o.x;
71347
71348          xi = -(a1 - a2) / (b1 - b2);
71349          // yi = a1 + b1 * xi;
71350        }
71351        // dont count xi < point.x cases
71352        if (xi >= point.x) {
71353          xcount += 1;
71354        }
71355        // optimisation 4: specific for square images
71356        if (xcount === 2) {
71357          break;
71358        }
71359      }
71360      return xcount;
71361    },
71362
71363    /**
71364     * Returns coordinates of object's bounding rectangle (left, top, width, height)
71365     * the box is intended as aligned to axis of canvas.
71366     * @param {Boolean} [absolute] use coordinates without viewportTransform
71367     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords / .aCoords
71368     * @return {Object} Object with left, top, width, height properties
71369     */
71370    getBoundingRect: function(absolute, calculate) {
71371      var coords = this.getCoords(absolute, calculate);
71372      return util.makeBoundingBoxFromPoints(coords);
71373    },
71374
71375    /**
71376     * Returns width of an object's bounding box counting transformations
71377     * before 2.0 it was named getWidth();
71378     * @return {Number} width value
71379     */
71380    getScaledWidth: function() {
71381      return this._getTransformedDimensions().x;
71382    },
71383
71384    /**
71385     * Returns height of an object bounding box counting transformations
71386     * before 2.0 it was named getHeight();
71387     * @return {Number} height value
71388     */
71389    getScaledHeight: function() {
71390      return this._getTransformedDimensions().y;
71391    },
71392
71393    /**
71394     * Makes sure the scale is valid and modifies it if necessary
71395     * @private
71396     * @param {Number} value
71397     * @return {Number}
71398     */
71399    _constrainScale: function(value) {
71400      if (Math.abs(value) < this.minScaleLimit) {
71401        if (value < 0) {
71402          return -this.minScaleLimit;
71403        }
71404        else {
71405          return this.minScaleLimit;
71406        }
71407      }
71408      else if (value === 0) {
71409        return 0.0001;
71410      }
71411      return value;
71412    },
71413
71414    /**
71415     * Scales an object (equally by x and y)
71416     * @param {Number} value Scale factor
71417     * @return {fabric.Object} thisArg
71418     * @chainable
71419     */
71420    scale: function(value) {
71421      this._set('scaleX', value);
71422      this._set('scaleY', value);
71423      return this.setCoords();
71424    },
71425
71426    /**
71427     * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)
71428     * @param {Number} value New width value
71429     * @param {Boolean} absolute ignore viewport
71430     * @return {fabric.Object} thisArg
71431     * @chainable
71432     */
71433    scaleToWidth: function(value, absolute) {
71434      // adjust to bounding rect factor so that rotated shapes would fit as well
71435      var boundingRectFactor = this.getBoundingRect(absolute).width / this.getScaledWidth();
71436      return this.scale(value / this.width / boundingRectFactor);
71437    },
71438
71439    /**
71440     * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)
71441     * @param {Number} value New height value
71442     * @param {Boolean} absolute ignore viewport
71443     * @return {fabric.Object} thisArg
71444     * @chainable
71445     */
71446    scaleToHeight: function(value, absolute) {
71447      // adjust to bounding rect factor so that rotated shapes would fit as well
71448      var boundingRectFactor = this.getBoundingRect(absolute).height / this.getScaledHeight();
71449      return this.scale(value / this.height / boundingRectFactor);
71450    },
71451
71452    /**
71453     * Calculates and returns the .coords of an object.
71454     * unused by the library, only for the end dev.
71455     * @return {Object} Object with tl, tr, br, bl ....
71456     * @chainable
71457     * @deprecated
71458     */
71459    calcCoords: function(absolute) {
71460      // this is a compatibility function to avoid removing calcCoords now.
71461      if (absolute) {
71462        return this.calcACoords();
71463      }
71464      return this.calcOCoords();
71465    },
71466
71467    calcLineCoords: function() {
71468      var vpt = this.getViewportTransform(),
71469          padding = this.padding, angle = degreesToRadians(this.angle),
71470          cos = util.cos(angle), sin = util.sin(angle),
71471          cosP = cos * padding, sinP = sin * padding, cosPSinP = cosP + sinP,
71472          cosPMinusSinP = cosP - sinP, aCoords = this.calcACoords();
71473
71474      var lineCoords = {
71475        tl: transformPoint(aCoords.tl, vpt),
71476        tr: transformPoint(aCoords.tr, vpt),
71477        bl: transformPoint(aCoords.bl, vpt),
71478        br: transformPoint(aCoords.br, vpt),
71479      };
71480
71481      if (padding) {
71482        lineCoords.tl.x -= cosPMinusSinP;
71483        lineCoords.tl.y -= cosPSinP;
71484        lineCoords.tr.x += cosPSinP;
71485        lineCoords.tr.y -= cosPMinusSinP;
71486        lineCoords.bl.x -= cosPSinP;
71487        lineCoords.bl.y += cosPMinusSinP;
71488        lineCoords.br.x += cosPMinusSinP;
71489        lineCoords.br.y += cosPSinP;
71490      }
71491
71492      return lineCoords;
71493    },
71494
71495    calcOCoords: function() {
71496      var rotateMatrix = this._calcRotateMatrix(),
71497          translateMatrix = this._calcTranslateMatrix(),
71498          vpt = this.getViewportTransform(),
71499          startMatrix = multiplyMatrices(vpt, translateMatrix),
71500          finalMatrix = multiplyMatrices(startMatrix, rotateMatrix),
71501          finalMatrix = multiplyMatrices(finalMatrix, [1 / vpt[0], 0, 0, 1 / vpt[3], 0, 0]),
71502          dim = this._calculateCurrentDimensions(),
71503          coords = {};
71504      this.forEachControl(function(control, key, fabricObject) {
71505        coords[key] = control.positionHandler(dim, finalMatrix, fabricObject);
71506      });
71507
71508      // debug code
71509      // var canvas = this.canvas;
71510      // setTimeout(function() {
71511      //   canvas.contextTop.clearRect(0, 0, 700, 700);
71512      //   canvas.contextTop.fillStyle = 'green';
71513      //   Object.keys(coords).forEach(function(key) {
71514      //     var control = coords[key];
71515      //     canvas.contextTop.fillRect(control.x, control.y, 3, 3);
71516      //   });
71517      // }, 50);
71518      return coords;
71519    },
71520
71521    calcACoords: function() {
71522      var rotateMatrix = this._calcRotateMatrix(),
71523          translateMatrix = this._calcTranslateMatrix(),
71524          finalMatrix = multiplyMatrices(translateMatrix, rotateMatrix),
71525          dim = this._getTransformedDimensions(),
71526          w = dim.x / 2, h = dim.y / 2;
71527      return {
71528        // corners
71529        tl: transformPoint({ x: -w, y: -h }, finalMatrix),
71530        tr: transformPoint({ x: w, y: -h }, finalMatrix),
71531        bl: transformPoint({ x: -w, y: h }, finalMatrix),
71532        br: transformPoint({ x: w, y: h }, finalMatrix)
71533      };
71534    },
71535
71536    /**
71537     * Sets corner and controls position coordinates based on current angle, width and height, left and top.
71538     * oCoords are used to find the corners
71539     * aCoords are used to quickly find an object on the canvas
71540     * lineCoords are used to quickly find object during pointer events.
71541     * See {@link https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords|When-to-call-setCoords}
71542     * @param {Boolean} [skipCorners] skip calculation of oCoords.
71543     * @return {fabric.Object} thisArg
71544     * @chainable
71545     */
71546    setCoords: function(skipCorners) {
71547      this.aCoords = this.calcACoords();
71548      // in case we are in a group, for how the inner group target check works,
71549      // lineCoords are exactly aCoords. Since the vpt gets absorbed by the normalized pointer.
71550      this.lineCoords = this.group ? this.aCoords : this.calcLineCoords();
71551      if (skipCorners) {
71552        return this;
71553      }
71554      // set coordinates of the draggable boxes in the corners used to scale/rotate the image
71555      this.oCoords = this.calcOCoords();
71556      this._setCornerCoords && this._setCornerCoords();
71557      return this;
71558    },
71559
71560    /**
71561     * calculate rotation matrix of an object
71562     * @return {Array} rotation matrix for the object
71563     */
71564    _calcRotateMatrix: function() {
71565      return util.calcRotateMatrix(this);
71566    },
71567
71568    /**
71569     * calculate the translation matrix for an object transform
71570     * @return {Array} rotation matrix for the object
71571     */
71572    _calcTranslateMatrix: function() {
71573      var center = this.getCenterPoint();
71574      return [1, 0, 0, 1, center.x, center.y];
71575    },
71576
71577    transformMatrixKey: function(skipGroup) {
71578      var sep = '_', prefix = '';
71579      if (!skipGroup && this.group) {
71580        prefix = this.group.transformMatrixKey(skipGroup) + sep;
71581      };
71582      return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY +
71583        sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.originX + sep + this.originY +
71584        sep + this.width + sep + this.height + sep + this.strokeWidth + this.flipX + this.flipY;
71585    },
71586
71587    /**
71588     * calculate transform matrix that represents the current transformations from the
71589     * object's properties.
71590     * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations
71591     * There are some situation in which this is useful to avoid the fake rotation.
71592     * @return {Array} transform matrix for the object
71593     */
71594    calcTransformMatrix: function(skipGroup) {
71595      var matrix = this.calcOwnMatrix();
71596      if (skipGroup || !this.group) {
71597        return matrix;
71598      }
71599      var key = this.transformMatrixKey(skipGroup), cache = this.matrixCache || (this.matrixCache = {});
71600      if (cache.key === key) {
71601        return cache.value;
71602      }
71603      if (this.group) {
71604        matrix = multiplyMatrices(this.group.calcTransformMatrix(false), matrix);
71605      }
71606      cache.key = key;
71607      cache.value = matrix;
71608      return matrix;
71609    },
71610
71611    /**
71612     * calculate transform matrix that represents the current transformations from the
71613     * object's properties, this matrix does not include the group transformation
71614     * @return {Array} transform matrix for the object
71615     */
71616    calcOwnMatrix: function() {
71617      var key = this.transformMatrixKey(true), cache = this.ownMatrixCache || (this.ownMatrixCache = {});
71618      if (cache.key === key) {
71619        return cache.value;
71620      }
71621      var tMatrix = this._calcTranslateMatrix(),
71622          options = {
71623            angle: this.angle,
71624            translateX: tMatrix[4],
71625            translateY: tMatrix[5],
71626            scaleX: this.scaleX,
71627            scaleY: this.scaleY,
71628            skewX: this.skewX,
71629            skewY: this.skewY,
71630            flipX: this.flipX,
71631            flipY: this.flipY,
71632          };
71633      cache.key = key;
71634      cache.value = util.composeMatrix(options);
71635      return cache.value;
71636    },
71637
71638    /*
71639     * Calculate object dimensions from its properties
71640     * @private
71641     * @deprecated since 3.4.0, please use fabric.util._calcDimensionsTransformMatrix
71642     * not including or including flipX, flipY to emulate the flipping boolean
71643     * @return {Object} .x width dimension
71644     * @return {Object} .y height dimension
71645     */
71646    _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) {
71647      return util.calcDimensionsMatrix({
71648        skewX: skewX,
71649        skewY: skewY,
71650        scaleX: this.scaleX * (flipping && this.flipX ? -1 : 1),
71651        scaleY: this.scaleY * (flipping && this.flipY ? -1 : 1)
71652      });
71653    },
71654
71655    /*
71656     * Calculate object dimensions from its properties
71657     * @private
71658     * @return {Object} .x width dimension
71659     * @return {Object} .y height dimension
71660     */
71661    _getNonTransformedDimensions: function() {
71662      var strokeWidth = this.strokeWidth,
71663          w = this.width + strokeWidth,
71664          h = this.height + strokeWidth;
71665      return { x: w, y: h };
71666    },
71667
71668    /*
71669     * Calculate object bounding box dimensions from its properties scale, skew.
71670     * @param {Number} skewX, a value to override current skewX
71671     * @param {Number} skewY, a value to override current skewY
71672     * @private
71673     * @return {Object} .x width dimension
71674     * @return {Object} .y height dimension
71675     */
71676    _getTransformedDimensions: function(skewX, skewY) {
71677      if (typeof skewX === 'undefined') {
71678        skewX = this.skewX;
71679      }
71680      if (typeof skewY === 'undefined') {
71681        skewY = this.skewY;
71682      }
71683      var dimensions, dimX, dimY,
71684          noSkew = skewX === 0 && skewY === 0;
71685
71686      if (this.strokeUniform) {
71687        dimX = this.width;
71688        dimY = this.height;
71689      }
71690      else {
71691        dimensions = this._getNonTransformedDimensions();
71692        dimX = dimensions.x;
71693        dimY = dimensions.y;
71694      }
71695      if (noSkew) {
71696        return this._finalizeDimensions(dimX * this.scaleX, dimY * this.scaleY);
71697      }
71698      var bbox = util.sizeAfterTransform(dimX, dimY, {
71699        scaleX: this.scaleX,
71700        scaleY: this.scaleY,
71701        skewX: skewX,
71702        skewY: skewY,
71703      });
71704      return this._finalizeDimensions(bbox.x, bbox.y);
71705    },
71706
71707    /*
71708     * Calculate object bounding box dimensions from its properties scale, skew.
71709     * @param Number width width of the bbox
71710     * @param Number height height of the bbox
71711     * @private
71712     * @return {Object} .x finalized width dimension
71713     * @return {Object} .y finalized height dimension
71714     */
71715    _finalizeDimensions: function(width, height) {
71716      return this.strokeUniform ?
71717        { x: width + this.strokeWidth, y: height + this.strokeWidth }
71718        :
71719        { x: width, y: height };
71720    },
71721
71722    /*
71723     * Calculate object dimensions for controls box, including padding and canvas zoom.
71724     * and active selection
71725     * private
71726     */
71727    _calculateCurrentDimensions: function()  {
71728      var vpt = this.getViewportTransform(),
71729          dim = this._getTransformedDimensions(),
71730          p = transformPoint(dim, vpt, true);
71731      return p.scalarAdd(2 * this.padding);
71732    },
71733  });
71734})();
71735
71736
71737fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {
71738
71739  /**
71740   * Moves an object to the bottom of the stack of drawn objects
71741   * @return {fabric.Object} thisArg
71742   * @chainable
71743   */
71744  sendToBack: function() {
71745    if (this.group) {
71746      fabric.StaticCanvas.prototype.sendToBack.call(this.group, this);
71747    }
71748    else if (this.canvas) {
71749      this.canvas.sendToBack(this);
71750    }
71751    return this;
71752  },
71753
71754  /**
71755   * Moves an object to the top of the stack of drawn objects
71756   * @return {fabric.Object} thisArg
71757   * @chainable
71758   */
71759  bringToFront: function() {
71760    if (this.group) {
71761      fabric.StaticCanvas.prototype.bringToFront.call(this.group, this);
71762    }
71763    else if (this.canvas) {
71764      this.canvas.bringToFront(this);
71765    }
71766    return this;
71767  },
71768
71769  /**
71770   * Moves an object down in stack of drawn objects
71771   * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object
71772   * @return {fabric.Object} thisArg
71773   * @chainable
71774   */
71775  sendBackwards: function(intersecting) {
71776    if (this.group) {
71777      fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting);
71778    }
71779    else if (this.canvas) {
71780      this.canvas.sendBackwards(this, intersecting);
71781    }
71782    return this;
71783  },
71784
71785  /**
71786   * Moves an object up in stack of drawn objects
71787   * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object
71788   * @return {fabric.Object} thisArg
71789   * @chainable
71790   */
71791  bringForward: function(intersecting) {
71792    if (this.group) {
71793      fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting);
71794    }
71795    else if (this.canvas) {
71796      this.canvas.bringForward(this, intersecting);
71797    }
71798    return this;
71799  },
71800
71801  /**
71802   * Moves an object to specified level in stack of drawn objects
71803   * @param {Number} index New position of object
71804   * @return {fabric.Object} thisArg
71805   * @chainable
71806   */
71807  moveTo: function(index) {
71808    if (this.group && this.group.type !== 'activeSelection') {
71809      fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index);
71810    }
71811    else if (this.canvas) {
71812      this.canvas.moveTo(this, index);
71813    }
71814    return this;
71815  }
71816});
71817
71818
71819/* _TO_SVG_START_ */
71820(function() {
71821  function getSvgColorString(prop, value) {
71822    if (!value) {
71823      return prop + ': none; ';
71824    }
71825    else if (value.toLive) {
71826      return prop + ': url(#SVGID_' + value.id + '); ';
71827    }
71828    else {
71829      var color = new fabric.Color(value),
71830          str = prop + ': ' + color.toRgb() + '; ',
71831          opacity = color.getAlpha();
71832      if (opacity !== 1) {
71833        //change the color in rgb + opacity
71834        str += prop + '-opacity: ' + opacity.toString() + '; ';
71835      }
71836      return str;
71837    }
71838  }
71839
71840  var toFixed = fabric.util.toFixed;
71841
71842  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {
71843    /**
71844     * Returns styles-string for svg-export
71845     * @param {Boolean} skipShadow a boolean to skip shadow filter output
71846     * @return {String}
71847     */
71848    getSvgStyles: function(skipShadow) {
71849
71850      var fillRule = this.fillRule ? this.fillRule : 'nonzero',
71851          strokeWidth = this.strokeWidth ? this.strokeWidth : '0',
71852          strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none',
71853          strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0',
71854          strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',
71855          strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter',
71856          strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4',
71857          opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1',
71858          visibility = this.visible ? '' : ' visibility: hidden;',
71859          filter = skipShadow ? '' : this.getSvgFilter(),
71860          fill = getSvgColorString('fill', this.fill),
71861          stroke = getSvgColorString('stroke', this.stroke);
71862
71863      return [
71864        stroke,
71865        'stroke-width: ', strokeWidth, '; ',
71866        'stroke-dasharray: ', strokeDashArray, '; ',
71867        'stroke-linecap: ', strokeLineCap, '; ',
71868        'stroke-dashoffset: ', strokeDashOffset, '; ',
71869        'stroke-linejoin: ', strokeLineJoin, '; ',
71870        'stroke-miterlimit: ', strokeMiterLimit, '; ',
71871        fill,
71872        'fill-rule: ', fillRule, '; ',
71873        'opacity: ', opacity, ';',
71874        filter,
71875        visibility
71876      ].join('');
71877    },
71878
71879    /**
71880     * Returns styles-string for svg-export
71881     * @param {Object} style the object from which to retrieve style properties
71882     * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.
71883     * @return {String}
71884     */
71885    getSvgSpanStyles: function(style, useWhiteSpace) {
71886      var term = '; ';
71887      var fontFamily = style.fontFamily ?
71888        'font-family: ' + (((style.fontFamily.indexOf('\'') === -1 && style.fontFamily.indexOf('"') === -1) ?
71889          '\'' + style.fontFamily  + '\'' : style.fontFamily)) + term : '';
71890      var strokeWidth = style.strokeWidth ? 'stroke-width: ' + style.strokeWidth + term : '',
71891          fontFamily = fontFamily,
71892          fontSize = style.fontSize ? 'font-size: ' + style.fontSize + 'px' + term : '',
71893          fontStyle = style.fontStyle ? 'font-style: ' + style.fontStyle + term : '',
71894          fontWeight = style.fontWeight ? 'font-weight: ' + style.fontWeight + term : '',
71895          fill = style.fill ? getSvgColorString('fill', style.fill) : '',
71896          stroke = style.stroke ? getSvgColorString('stroke', style.stroke) : '',
71897          textDecoration = this.getSvgTextDecoration(style),
71898          deltaY = style.deltaY ? 'baseline-shift: ' + (-style.deltaY) + '; ' : '';
71899      if (textDecoration) {
71900        textDecoration = 'text-decoration: ' + textDecoration + term;
71901      }
71902
71903      return [
71904        stroke,
71905        strokeWidth,
71906        fontFamily,
71907        fontSize,
71908        fontStyle,
71909        fontWeight,
71910        textDecoration,
71911        fill,
71912        deltaY,
71913        useWhiteSpace ? 'white-space: pre; ' : ''
71914      ].join('');
71915    },
71916
71917    /**
71918     * Returns text-decoration property for svg-export
71919     * @param {Object} style the object from which to retrieve style properties
71920     * @return {String}
71921     */
71922    getSvgTextDecoration: function(style) {
71923      return ['overline', 'underline', 'line-through'].filter(function(decoration) {
71924        return style[decoration.replace('-', '')];
71925      }).join(' ');
71926    },
71927
71928    /**
71929     * Returns filter for svg shadow
71930     * @return {String}
71931     */
71932    getSvgFilter: function() {
71933      return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : '';
71934    },
71935
71936    /**
71937     * Returns id attribute for svg output
71938     * @return {String}
71939     */
71940    getSvgCommons: function() {
71941      return [
71942        this.id ? 'id="' + this.id + '" ' : '',
71943        this.clipPath ? 'clip-path="url(#' + this.clipPath.clipPathId + ')" ' : '',
71944      ].join('');
71945    },
71946
71947    /**
71948     * Returns transform-string for svg-export
71949     * @param {Boolean} use the full transform or the single object one.
71950     * @return {String}
71951     */
71952    getSvgTransform: function(full, additionalTransform) {
71953      var transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(),
71954          svgTransform = 'transform="' + fabric.util.matrixToSVG(transform);
71955      return svgTransform +
71956        (additionalTransform || '') + '" ';
71957    },
71958
71959    _setSVGBg: function(textBgRects) {
71960      if (this.backgroundColor) {
71961        var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;
71962        textBgRects.push(
71963          '\t\t<rect ',
71964          this._getFillAttributes(this.backgroundColor),
71965          ' x="',
71966          toFixed(-this.width / 2, NUM_FRACTION_DIGITS),
71967          '" y="',
71968          toFixed(-this.height / 2, NUM_FRACTION_DIGITS),
71969          '" width="',
71970          toFixed(this.width, NUM_FRACTION_DIGITS),
71971          '" height="',
71972          toFixed(this.height, NUM_FRACTION_DIGITS),
71973          '"></rect>\n');
71974      }
71975    },
71976
71977    /**
71978     * Returns svg representation of an instance
71979     * @param {Function} [reviver] Method for further parsing of svg representation.
71980     * @return {String} svg representation of an instance
71981     */
71982    toSVG: function(reviver) {
71983      return this._createBaseSVGMarkup(this._toSVG(reviver), { reviver: reviver });
71984    },
71985
71986    /**
71987     * Returns svg clipPath representation of an instance
71988     * @param {Function} [reviver] Method for further parsing of svg representation.
71989     * @return {String} svg representation of an instance
71990     */
71991    toClipPathSVG: function(reviver) {
71992      return '\t' + this._createBaseClipPathSVGMarkup(this._toSVG(reviver), { reviver: reviver });
71993    },
71994
71995    /**
71996     * @private
71997     */
71998    _createBaseClipPathSVGMarkup: function(objectMarkup, options) {
71999      options = options || {};
72000      var reviver = options.reviver,
72001          additionalTransform = options.additionalTransform || '',
72002          commonPieces = [
72003            this.getSvgTransform(true, additionalTransform),
72004            this.getSvgCommons(),
72005          ].join(''),
72006          // insert commons in the markup, style and svgCommons
72007          index = objectMarkup.indexOf('COMMON_PARTS');
72008      objectMarkup[index] = commonPieces;
72009      return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join('');
72010    },
72011
72012    /**
72013     * @private
72014     */
72015    _createBaseSVGMarkup: function(objectMarkup, options) {
72016      options = options || {};
72017      var noStyle = options.noStyle,
72018          reviver = options.reviver,
72019          styleInfo = noStyle ? '' : 'style="' + this.getSvgStyles() + '" ',
72020          shadowInfo = options.withShadow ? 'style="' + this.getSvgFilter() + '" ' : '',
72021          clipPath = this.clipPath,
72022          vectorEffect = this.strokeUniform ? 'vector-effect="non-scaling-stroke" ' : '',
72023          absoluteClipPath = clipPath && clipPath.absolutePositioned,
72024          stroke = this.stroke, fill = this.fill, shadow = this.shadow,
72025          commonPieces, markup = [], clipPathMarkup,
72026          // insert commons in the markup, style and svgCommons
72027          index = objectMarkup.indexOf('COMMON_PARTS'),
72028          additionalTransform = options.additionalTransform;
72029      if (clipPath) {
72030        clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;
72031        clipPathMarkup = '<clipPath id="' + clipPath.clipPathId + '" >\n' +
72032          clipPath.toClipPathSVG(reviver) +
72033          '</clipPath>\n';
72034      }
72035      if (absoluteClipPath) {
72036        markup.push(
72037          '<g ', shadowInfo, this.getSvgCommons(), ' >\n'
72038        );
72039      }
72040      markup.push(
72041        '<g ',
72042        this.getSvgTransform(false),
72043        !absoluteClipPath ? shadowInfo + this.getSvgCommons() : '',
72044        ' >\n'
72045      );
72046      commonPieces = [
72047        styleInfo,
72048        vectorEffect,
72049        noStyle ? '' : this.addPaintOrder(), ' ',
72050        additionalTransform ? 'transform="' + additionalTransform + '" ' : '',
72051      ].join('');
72052      objectMarkup[index] = commonPieces;
72053      if (fill && fill.toLive) {
72054        markup.push(fill.toSVG(this));
72055      }
72056      if (stroke && stroke.toLive) {
72057        markup.push(stroke.toSVG(this));
72058      }
72059      if (shadow) {
72060        markup.push(shadow.toSVG(this));
72061      }
72062      if (clipPath) {
72063        markup.push(clipPathMarkup);
72064      }
72065      markup.push(objectMarkup.join(''));
72066      markup.push('</g>\n');
72067      absoluteClipPath && markup.push('</g>\n');
72068      return reviver ? reviver(markup.join('')) : markup.join('');
72069    },
72070
72071    addPaintOrder: function() {
72072      return this.paintFirst !== 'fill' ? ' paint-order="' + this.paintFirst + '" ' : '';
72073    }
72074  });
72075})();
72076/* _TO_SVG_END_ */
72077
72078
72079(function() {
72080
72081  var extend = fabric.util.object.extend,
72082      originalSet = 'stateProperties';
72083
72084  /*
72085    Depends on `stateProperties`
72086  */
72087  function saveProps(origin, destination, props) {
72088    var tmpObj = { }, deep = true;
72089    props.forEach(function(prop) {
72090      tmpObj[prop] = origin[prop];
72091    });
72092
72093    extend(origin[destination], tmpObj, deep);
72094  }
72095
72096  function _isEqual(origValue, currentValue, firstPass) {
72097    if (origValue === currentValue) {
72098      // if the objects are identical, return
72099      return true;
72100    }
72101    else if (Array.isArray(origValue)) {
72102      if (!Array.isArray(currentValue) || origValue.length !== currentValue.length) {
72103        return false;
72104      }
72105      for (var i = 0, len = origValue.length; i < len; i++) {
72106        if (!_isEqual(origValue[i], currentValue[i])) {
72107          return false;
72108        }
72109      }
72110      return true;
72111    }
72112    else if (origValue && typeof origValue === 'object') {
72113      var keys = Object.keys(origValue), key;
72114      if (!currentValue ||
72115          typeof currentValue !== 'object' ||
72116          (!firstPass && keys.length !== Object.keys(currentValue).length)
72117      ) {
72118        return false;
72119      }
72120      for (var i = 0, len = keys.length; i < len; i++) {
72121        key = keys[i];
72122        // since clipPath is in the statefull cache list and the clipPath objects
72123        // would be iterated as an object, this would lead to possible infinite recursion
72124        // we do not want to compare those.
72125        if (key === 'canvas' || key === 'group') {
72126          continue;
72127        }
72128        if (!_isEqual(origValue[key], currentValue[key])) {
72129          return false;
72130        }
72131      }
72132      return true;
72133    }
72134  }
72135
72136
72137  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {
72138
72139    /**
72140     * Returns true if object state (one of its state properties) was changed
72141     * @param {String} [propertySet] optional name for the set of property we want to save
72142     * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called
72143     */
72144    hasStateChanged: function(propertySet) {
72145      propertySet = propertySet || originalSet;
72146      var dashedPropertySet = '_' + propertySet;
72147      if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) {
72148        return true;
72149      }
72150      return !_isEqual(this[dashedPropertySet], this, true);
72151    },
72152
72153    /**
72154     * Saves state of an object
72155     * @param {Object} [options] Object with additional `stateProperties` array to include when saving state
72156     * @return {fabric.Object} thisArg
72157     */
72158    saveState: function(options) {
72159      var propertySet = options && options.propertySet || originalSet,
72160          destination = '_' + propertySet;
72161      if (!this[destination]) {
72162        return this.setupState(options);
72163      }
72164      saveProps(this, destination, this[propertySet]);
72165      if (options && options.stateProperties) {
72166        saveProps(this, destination, options.stateProperties);
72167      }
72168      return this;
72169    },
72170
72171    /**
72172     * Setups state of an object
72173     * @param {Object} [options] Object with additional `stateProperties` array to include when saving state
72174     * @return {fabric.Object} thisArg
72175     */
72176    setupState: function(options) {
72177      options = options || { };
72178      var propertySet = options.propertySet || originalSet;
72179      options.propertySet = propertySet;
72180      this['_' + propertySet] = { };
72181      this.saveState(options);
72182      return this;
72183    }
72184  });
72185})();
72186
72187
72188(function() {
72189
72190  var degreesToRadians = fabric.util.degreesToRadians;
72191
72192  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {
72193    /**
72194     * Determines which corner has been clicked
72195     * @private
72196     * @param {Object} pointer The pointer indicating the mouse position
72197     * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found
72198     */
72199    _findTargetCorner: function(pointer, forTouch) {
72200      // objects in group, anykind, are not self modificable,
72201      // must not return an hovered corner.
72202      if (!this.hasControls || this.group || (!this.canvas || this.canvas._activeObject !== this)) {
72203        return false;
72204      }
72205
72206      var ex = pointer.x,
72207          ey = pointer.y,
72208          xPoints,
72209          lines, keys = Object.keys(this.oCoords),
72210          j = keys.length - 1, i;
72211      this.__corner = 0;
72212
72213      // cycle in reverse order so we pick first the one on top
72214      for (; j >= 0; j--) {
72215        i = keys[j];
72216        if (!this.isControlVisible(i)) {
72217          continue;
72218        }
72219
72220        lines = this._getImageLines(forTouch ? this.oCoords[i].touchCorner : this.oCoords[i].corner);
72221        // // debugging
72222        //
72223        // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);
72224        // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);
72225        //
72226        // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);
72227        // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);
72228        //
72229        // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);
72230        // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);
72231        //
72232        // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);
72233        // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);
72234
72235        xPoints = this._findCrossPoints({ x: ex, y: ey }, lines);
72236        if (xPoints !== 0 && xPoints % 2 === 1) {
72237          this.__corner = i;
72238          return i;
72239        }
72240      }
72241      return false;
72242    },
72243
72244    /**
72245     * Calls a function for each control. The function gets called,
72246     * with the control, the object that is calling the iterator and the control's key
72247     * @param {Function} fn function to iterate over the controls over
72248     */
72249    forEachControl: function(fn) {
72250      for (var i in this.controls) {
72251        fn(this.controls[i], i, this);
72252      };
72253    },
72254
72255    /**
72256     * Sets the coordinates of the draggable boxes in the corners of
72257     * the image used to scale/rotate it.
72258     * note: if we would switch to ROUND corner area, all of this would disappear.
72259     * everything would resolve to a single point and a pythagorean theorem for the distance
72260     * @private
72261     */
72262    _setCornerCoords: function() {
72263      var coords = this.oCoords;
72264
72265      for (var control in coords) {
72266        var controlObject = this.controls[control];
72267        coords[control].corner = controlObject.calcCornerCoords(
72268          this.angle, this.cornerSize, coords[control].x, coords[control].y, false);
72269        coords[control].touchCorner = controlObject.calcCornerCoords(
72270          this.angle, this.touchCornerSize, coords[control].x, coords[control].y, true);
72271      }
72272    },
72273
72274    /**
72275     * Draws a colored layer behind the object, inside its selection borders.
72276     * Requires public options: padding, selectionBackgroundColor
72277     * this function is called when the context is transformed
72278     * has checks to be skipped when the object is on a staticCanvas
72279     * @param {CanvasRenderingContext2D} ctx Context to draw on
72280     * @return {fabric.Object} thisArg
72281     * @chainable
72282     */
72283    drawSelectionBackground: function(ctx) {
72284      if (!this.selectionBackgroundColor ||
72285        (this.canvas && !this.canvas.interactive) ||
72286        (this.canvas && this.canvas._activeObject !== this)
72287      ) {
72288        return this;
72289      }
72290      ctx.save();
72291      var center = this.getCenterPoint(), wh = this._calculateCurrentDimensions(),
72292          vpt = this.canvas.viewportTransform;
72293      ctx.translate(center.x, center.y);
72294      ctx.scale(1 / vpt[0], 1 / vpt[3]);
72295      ctx.rotate(degreesToRadians(this.angle));
72296      ctx.fillStyle = this.selectionBackgroundColor;
72297      ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);
72298      ctx.restore();
72299      return this;
72300    },
72301
72302    /**
72303     * Draws borders of an object's bounding box.
72304     * Requires public properties: width, height
72305     * Requires public options: padding, borderColor
72306     * @param {CanvasRenderingContext2D} ctx Context to draw on
72307     * @param {Object} styleOverride object to override the object style
72308     * @return {fabric.Object} thisArg
72309     * @chainable
72310     */
72311    drawBorders: function(ctx, styleOverride) {
72312      styleOverride = styleOverride || {};
72313      var wh = this._calculateCurrentDimensions(),
72314          strokeWidth = this.borderScaleFactor,
72315          width = wh.x + strokeWidth,
72316          height = wh.y + strokeWidth,
72317          hasControls = typeof styleOverride.hasControls !== 'undefined' ?
72318            styleOverride.hasControls : this.hasControls,
72319          shouldStroke = false;
72320
72321      ctx.save();
72322      ctx.strokeStyle = styleOverride.borderColor || this.borderColor;
72323      this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray);
72324
72325      ctx.strokeRect(
72326        -width / 2,
72327        -height / 2,
72328        width,
72329        height
72330      );
72331
72332      if (hasControls) {
72333        ctx.beginPath();
72334        this.forEachControl(function(control, key, fabricObject) {
72335          // in this moment, the ctx is centered on the object.
72336          // width and height of the above function are the size of the bbox.
72337          if (control.withConnection && control.getVisibility(fabricObject, key)) {
72338            // reset movement for each control
72339            shouldStroke = true;
72340            ctx.moveTo(control.x * width, control.y * height);
72341            ctx.lineTo(
72342              control.x * width + control.offsetX,
72343              control.y * height + control.offsetY
72344            );
72345          }
72346        });
72347        if (shouldStroke) {
72348          ctx.stroke();
72349        }
72350      }
72351      ctx.restore();
72352      return this;
72353    },
72354
72355    /**
72356     * Draws borders of an object's bounding box when it is inside a group.
72357     * Requires public properties: width, height
72358     * Requires public options: padding, borderColor
72359     * @param {CanvasRenderingContext2D} ctx Context to draw on
72360     * @param {object} options object representing current object parameters
72361     * @param {Object} styleOverride object to override the object style
72362     * @return {fabric.Object} thisArg
72363     * @chainable
72364     */
72365    drawBordersInGroup: function(ctx, options, styleOverride) {
72366      styleOverride = styleOverride || {};
72367      var bbox = fabric.util.sizeAfterTransform(this.width, this.height, options),
72368          strokeWidth = this.strokeWidth,
72369          strokeUniform = this.strokeUniform,
72370          borderScaleFactor = this.borderScaleFactor,
72371          width =
72372            bbox.x + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleX) + borderScaleFactor,
72373          height =
72374            bbox.y + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleY) + borderScaleFactor;
72375      ctx.save();
72376      this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray);
72377      ctx.strokeStyle = styleOverride.borderColor || this.borderColor;
72378      ctx.strokeRect(
72379        -width / 2,
72380        -height / 2,
72381        width,
72382        height
72383      );
72384
72385      ctx.restore();
72386      return this;
72387    },
72388
72389    /**
72390     * Draws corners of an object's bounding box.
72391     * Requires public properties: width, height
72392     * Requires public options: cornerSize, padding
72393     * @param {CanvasRenderingContext2D} ctx Context to draw on
72394     * @param {Object} styleOverride object to override the object style
72395     * @return {fabric.Object} thisArg
72396     * @chainable
72397     */
72398    drawControls: function(ctx, styleOverride) {
72399      styleOverride = styleOverride || {};
72400      ctx.save();
72401      var retinaScaling = this.canvas.getRetinaScaling(), matrix, p;
72402      ctx.setTransform(retinaScaling, 0, 0, retinaScaling, 0, 0);
72403      ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor;
72404      if (!this.transparentCorners) {
72405        ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor;
72406      }
72407      this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray);
72408      this.setCoords();
72409      if (this.group) {
72410        // fabricJS does not really support drawing controls inside groups,
72411        // this piece of code here helps having at least the control in places.
72412        // If an application needs to show some objects as selected because of some UI state
72413        // can still call Object._renderControls() on any object they desire, independently of groups.
72414        // using no padding, circular controls and hiding the rotating cursor is higly suggested,
72415        matrix = this.group.calcTransformMatrix();
72416      }
72417      this.forEachControl(function(control, key, fabricObject) {
72418        p = fabricObject.oCoords[key];
72419        if (control.getVisibility(fabricObject, key)) {
72420          if (matrix) {
72421            p = fabric.util.transformPoint(p, matrix);
72422          }
72423          control.render(ctx, p.x, p.y, styleOverride, fabricObject);
72424        }
72425      });
72426      ctx.restore();
72427
72428      return this;
72429    },
72430
72431    /**
72432     * Returns true if the specified control is visible, false otherwise.
72433     * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.
72434     * @returns {Boolean} true if the specified control is visible, false otherwise
72435     */
72436    isControlVisible: function(controlKey) {
72437      return this.controls[controlKey] && this.controls[controlKey].getVisibility(this, controlKey);
72438    },
72439
72440    /**
72441     * Sets the visibility of the specified control.
72442     * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.
72443     * @param {Boolean} visible true to set the specified control visible, false otherwise
72444     * @return {fabric.Object} thisArg
72445     * @chainable
72446     */
72447    setControlVisible: function(controlKey, visible) {
72448      if (!this._controlsVisibility) {
72449        this._controlsVisibility = {};
72450      }
72451      this._controlsVisibility[controlKey] = visible;
72452      return this;
72453    },
72454
72455    /**
72456     * Sets the visibility state of object controls.
72457     * @param {Object} [options] Options object
72458     * @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it
72459     * @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it
72460     * @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it
72461     * @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it
72462     * @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it
72463     * @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it
72464     * @param {Boolean} [options.tl] true to enable the top-left control, false to disable it
72465     * @param {Boolean} [options.tr] true to enable the top-right control, false to disable it
72466     * @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it
72467     * @return {fabric.Object} thisArg
72468     * @chainable
72469     */
72470    setControlsVisibility: function(options) {
72471      options || (options = { });
72472
72473      for (var p in options) {
72474        this.setControlVisible(p, options[p]);
72475      }
72476      return this;
72477    },
72478
72479
72480    /**
72481     * This callback function is called every time _discardActiveObject or _setActiveObject
72482     * try to to deselect this object. If the function returns true, the process is cancelled
72483     * @param {Object} [options] options sent from the upper functions
72484     * @param {Event} [options.e] event if the process is generated by an event
72485     */
72486    onDeselect: function() {
72487      // implemented by sub-classes, as needed.
72488    },
72489
72490
72491    /**
72492     * This callback function is called every time _discardActiveObject or _setActiveObject
72493     * try to to select this object. If the function returns true, the process is cancelled
72494     * @param {Object} [options] options sent from the upper functions
72495     * @param {Event} [options.e] event if the process is generated by an event
72496     */
72497    onSelect: function() {
72498      // implemented by sub-classes, as needed.
72499    }
72500  });
72501})();
72502
72503
72504fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {
72505
72506  /**
72507   * Animation duration (in ms) for fx* methods
72508   * @type Number
72509   * @default
72510   */
72511  FX_DURATION: 500,
72512
72513  /**
72514   * Centers object horizontally with animation.
72515   * @param {fabric.Object} object Object to center
72516   * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties
72517   * @param {Function} [callbacks.onComplete] Invoked on completion
72518   * @param {Function} [callbacks.onChange] Invoked on every step of animation
72519   * @return {fabric.Canvas} thisArg
72520   * @chainable
72521   */
72522  fxCenterObjectH: function (object, callbacks) {
72523    callbacks = callbacks || { };
72524
72525    var empty = function() { },
72526        onComplete = callbacks.onComplete || empty,
72527        onChange = callbacks.onChange || empty,
72528        _this = this;
72529
72530    fabric.util.animate({
72531      startValue: object.left,
72532      endValue: this.getCenter().left,
72533      duration: this.FX_DURATION,
72534      onChange: function(value) {
72535        object.set('left', value);
72536        _this.requestRenderAll();
72537        onChange();
72538      },
72539      onComplete: function() {
72540        object.setCoords();
72541        onComplete();
72542      }
72543    });
72544
72545    return this;
72546  },
72547
72548  /**
72549   * Centers object vertically with animation.
72550   * @param {fabric.Object} object Object to center
72551   * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties
72552   * @param {Function} [callbacks.onComplete] Invoked on completion
72553   * @param {Function} [callbacks.onChange] Invoked on every step of animation
72554   * @return {fabric.Canvas} thisArg
72555   * @chainable
72556   */
72557  fxCenterObjectV: function (object, callbacks) {
72558    callbacks = callbacks || { };
72559
72560    var empty = function() { },
72561        onComplete = callbacks.onComplete || empty,
72562        onChange = callbacks.onChange || empty,
72563        _this = this;
72564
72565    fabric.util.animate({
72566      startValue: object.top,
72567      endValue: this.getCenter().top,
72568      duration: this.FX_DURATION,
72569      onChange: function(value) {
72570        object.set('top', value);
72571        _this.requestRenderAll();
72572        onChange();
72573      },
72574      onComplete: function() {
72575        object.setCoords();
72576        onComplete();
72577      }
72578    });
72579
72580    return this;
72581  },
72582
72583  /**
72584   * Same as `fabric.Canvas#remove` but animated
72585   * @param {fabric.Object} object Object to remove
72586   * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties
72587   * @param {Function} [callbacks.onComplete] Invoked on completion
72588   * @param {Function} [callbacks.onChange] Invoked on every step of animation
72589   * @return {fabric.Canvas} thisArg
72590   * @chainable
72591   */
72592  fxRemove: function (object, callbacks) {
72593    callbacks = callbacks || { };
72594
72595    var empty = function() { },
72596        onComplete = callbacks.onComplete || empty,
72597        onChange = callbacks.onChange || empty,
72598        _this = this;
72599
72600    fabric.util.animate({
72601      startValue: object.opacity,
72602      endValue: 0,
72603      duration: this.FX_DURATION,
72604      onChange: function(value) {
72605        object.set('opacity', value);
72606        _this.requestRenderAll();
72607        onChange();
72608      },
72609      onComplete: function () {
72610        _this.remove(object);
72611        onComplete();
72612      }
72613    });
72614
72615    return this;
72616  }
72617});
72618
72619fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {
72620  /**
72621   * Animates object's properties
72622   * @param {String|Object} property Property to animate (if string) or properties to animate (if object)
72623   * @param {Number|Object} value Value to animate property to (if string was given first) or options object
72624   * @return {fabric.Object} thisArg
72625   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}
72626   * @chainable
72627   *
72628   * As object — multiple properties
72629   *
72630   * object.animate({ left: ..., top: ... });
72631   * object.animate({ left: ..., top: ... }, { duration: ... });
72632   *
72633   * As string — one property
72634   *
72635   * object.animate('left', ...);
72636   * object.animate('left', { duration: ... });
72637   *
72638   */
72639  animate: function() {
72640    if (arguments[0] && typeof arguments[0] === 'object') {
72641      var propsToAnimate = [], prop, skipCallbacks;
72642      for (prop in arguments[0]) {
72643        propsToAnimate.push(prop);
72644      }
72645      for (var i = 0, len = propsToAnimate.length; i < len; i++) {
72646        prop = propsToAnimate[i];
72647        skipCallbacks = i !== len - 1;
72648        this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks);
72649      }
72650    }
72651    else {
72652      this._animate.apply(this, arguments);
72653    }
72654    return this;
72655  },
72656
72657  /**
72658   * @private
72659   * @param {String} property Property to animate
72660   * @param {String} to Value to animate to
72661   * @param {Object} [options] Options object
72662   * @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked
72663   */
72664  _animate: function(property, to, options, skipCallbacks) {
72665    var _this = this, propPair;
72666
72667    to = to.toString();
72668
72669    if (!options) {
72670      options = { };
72671    }
72672    else {
72673      options = fabric.util.object.clone(options);
72674    }
72675
72676    if (~property.indexOf('.')) {
72677      propPair = property.split('.');
72678    }
72679
72680    var propIsColor =
72681      _this.colorProperties.indexOf(property) > -1 ||
72682      (propPair && _this.colorProperties.indexOf(propPair[1]) > -1);
72683
72684    var currentValue = propPair
72685      ? this.get(propPair[0])[propPair[1]]
72686      : this.get(property);
72687
72688    if (!('from' in options)) {
72689      options.from = currentValue;
72690    }
72691
72692    if (!propIsColor) {
72693      if (~to.indexOf('=')) {
72694        to = currentValue + parseFloat(to.replace('=', ''));
72695      }
72696      else {
72697        to = parseFloat(to);
72698      }
72699    }
72700
72701    var _options = {
72702      startValue: options.from,
72703      endValue: to,
72704      byValue: options.by,
72705      easing: options.easing,
72706      duration: options.duration,
72707      abort: options.abort && function(value, valueProgress, timeProgress) {
72708        return options.abort.call(_this, value, valueProgress, timeProgress);
72709      },
72710      onChange: function (value, valueProgress, timeProgress) {
72711        if (propPair) {
72712          _this[propPair[0]][propPair[1]] = value;
72713        }
72714        else {
72715          _this.set(property, value);
72716        }
72717        if (skipCallbacks) {
72718          return;
72719        }
72720        options.onChange && options.onChange(value, valueProgress, timeProgress);
72721      },
72722      onComplete: function (value, valueProgress, timeProgress) {
72723        if (skipCallbacks) {
72724          return;
72725        }
72726
72727        _this.setCoords();
72728        options.onComplete && options.onComplete(value, valueProgress, timeProgress);
72729      }
72730    };
72731
72732    if (propIsColor) {
72733      return fabric.util.animateColor(_options.startValue, _options.endValue, _options.duration, _options);
72734    }
72735    else {
72736      return fabric.util.animate(_options);
72737    }
72738  }
72739});
72740
72741
72742(function(global) {
72743
72744  'use strict';
72745
72746  var fabric = global.fabric || (global.fabric = { }),
72747      extend = fabric.util.object.extend,
72748      clone = fabric.util.object.clone,
72749      coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 };
72750
72751  if (fabric.Line) {
72752    fabric.warn('fabric.Line is already defined');
72753    return;
72754  }
72755
72756  /**
72757   * Line class
72758   * @class fabric.Line
72759   * @extends fabric.Object
72760   * @see {@link fabric.Line#initialize} for constructor definition
72761   */
72762  fabric.Line = fabric.util.createClass(fabric.Object, /** @lends fabric.Line.prototype */ {
72763
72764    /**
72765     * Type of an object
72766     * @type String
72767     * @default
72768     */
72769    type: 'line',
72770
72771    /**
72772     * x value or first line edge
72773     * @type Number
72774     * @default
72775     */
72776    x1: 0,
72777
72778    /**
72779     * y value or first line edge
72780     * @type Number
72781     * @default
72782     */
72783    y1: 0,
72784
72785    /**
72786     * x value or second line edge
72787     * @type Number
72788     * @default
72789     */
72790    x2: 0,
72791
72792    /**
72793     * y value or second line edge
72794     * @type Number
72795     * @default
72796     */
72797    y2: 0,
72798
72799    cacheProperties: fabric.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'),
72800
72801    /**
72802     * Constructor
72803     * @param {Array} [points] Array of points
72804     * @param {Object} [options] Options object
72805     * @return {fabric.Line} thisArg
72806     */
72807    initialize: function(points, options) {
72808      if (!points) {
72809        points = [0, 0, 0, 0];
72810      }
72811
72812      this.callSuper('initialize', options);
72813
72814      this.set('x1', points[0]);
72815      this.set('y1', points[1]);
72816      this.set('x2', points[2]);
72817      this.set('y2', points[3]);
72818
72819      this._setWidthHeight(options);
72820    },
72821
72822    /**
72823     * @private
72824     * @param {Object} [options] Options
72825     */
72826    _setWidthHeight: function(options) {
72827      options || (options = { });
72828
72829      this.width = Math.abs(this.x2 - this.x1);
72830      this.height = Math.abs(this.y2 - this.y1);
72831
72832      this.left = 'left' in options
72833        ? options.left
72834        : this._getLeftToOriginX();
72835
72836      this.top = 'top' in options
72837        ? options.top
72838        : this._getTopToOriginY();
72839    },
72840
72841    /**
72842     * @private
72843     * @param {String} key
72844     * @param {*} value
72845     */
72846    _set: function(key, value) {
72847      this.callSuper('_set', key, value);
72848      if (typeof coordProps[key] !== 'undefined') {
72849        this._setWidthHeight();
72850      }
72851      return this;
72852    },
72853
72854    /**
72855     * @private
72856     * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line.
72857     */
72858    _getLeftToOriginX: makeEdgeToOriginGetter(
72859      { // property names
72860        origin: 'originX',
72861        axis1: 'x1',
72862        axis2: 'x2',
72863        dimension: 'width'
72864      },
72865      { // possible values of origin
72866        nearest: 'left',
72867        center: 'center',
72868        farthest: 'right'
72869      }
72870    ),
72871
72872    /**
72873     * @private
72874     * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line.
72875     */
72876    _getTopToOriginY: makeEdgeToOriginGetter(
72877      { // property names
72878        origin: 'originY',
72879        axis1: 'y1',
72880        axis2: 'y2',
72881        dimension: 'height'
72882      },
72883      { // possible values of origin
72884        nearest: 'top',
72885        center: 'center',
72886        farthest: 'bottom'
72887      }
72888    ),
72889
72890    /**
72891     * @private
72892     * @param {CanvasRenderingContext2D} ctx Context to render on
72893     */
72894    _render: function(ctx) {
72895      ctx.beginPath();
72896
72897
72898      var p = this.calcLinePoints();
72899      ctx.moveTo(p.x1, p.y1);
72900      ctx.lineTo(p.x2, p.y2);
72901
72902      ctx.lineWidth = this.strokeWidth;
72903
72904      // TODO: test this
72905      // make sure setting "fill" changes color of a line
72906      // (by copying fillStyle to strokeStyle, since line is stroked, not filled)
72907      var origStrokeStyle = ctx.strokeStyle;
72908      ctx.strokeStyle = this.stroke || ctx.fillStyle;
72909      this.stroke && this._renderStroke(ctx);
72910      ctx.strokeStyle = origStrokeStyle;
72911    },
72912
72913    /**
72914     * This function is an helper for svg import. it returns the center of the object in the svg
72915     * untransformed coordinates
72916     * @private
72917     * @return {Object} center point from element coordinates
72918     */
72919    _findCenterFromElement: function() {
72920      return {
72921        x: (this.x1 + this.x2) / 2,
72922        y: (this.y1 + this.y2) / 2,
72923      };
72924    },
72925
72926    /**
72927     * Returns object representation of an instance
72928     * @method toObject
72929     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
72930     * @return {Object} object representation of an instance
72931     */
72932    toObject: function(propertiesToInclude) {
72933      return extend(this.callSuper('toObject', propertiesToInclude), this.calcLinePoints());
72934    },
72935
72936    /*
72937     * Calculate object dimensions from its properties
72938     * @private
72939     */
72940    _getNonTransformedDimensions: function() {
72941      var dim = this.callSuper('_getNonTransformedDimensions');
72942      if (this.strokeLineCap === 'butt') {
72943        if (this.width === 0) {
72944          dim.y -= this.strokeWidth;
72945        }
72946        if (this.height === 0) {
72947          dim.x -= this.strokeWidth;
72948        }
72949      }
72950      return dim;
72951    },
72952
72953    /**
72954     * Recalculates line points given width and height
72955     * @private
72956     */
72957    calcLinePoints: function() {
72958      var xMult = this.x1 <= this.x2 ? -1 : 1,
72959          yMult = this.y1 <= this.y2 ? -1 : 1,
72960          x1 = (xMult * this.width * 0.5),
72961          y1 = (yMult * this.height * 0.5),
72962          x2 = (xMult * this.width * -0.5),
72963          y2 = (yMult * this.height * -0.5);
72964
72965      return {
72966        x1: x1,
72967        x2: x2,
72968        y1: y1,
72969        y2: y2
72970      };
72971    },
72972
72973    /* _TO_SVG_START_ */
72974    /**
72975     * Returns svg representation of an instance
72976     * @return {Array} an array of strings with the specific svg representation
72977     * of the instance
72978     */
72979    _toSVG: function() {
72980      var p = this.calcLinePoints();
72981      return [
72982        '<line ', 'COMMON_PARTS',
72983        'x1="', p.x1,
72984        '" y1="', p.y1,
72985        '" x2="', p.x2,
72986        '" y2="', p.y2,
72987        '" />\n'
72988      ];
72989    },
72990    /* _TO_SVG_END_ */
72991  });
72992
72993  /* _FROM_SVG_START_ */
72994  /**
72995   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement})
72996   * @static
72997   * @memberOf fabric.Line
72998   * @see http://www.w3.org/TR/SVG/shapes.html#LineElement
72999   */
73000  fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' '));
73001
73002  /**
73003   * Returns fabric.Line instance from an SVG element
73004   * @static
73005   * @memberOf fabric.Line
73006   * @param {SVGElement} element Element to parse
73007   * @param {Object} [options] Options object
73008   * @param {Function} [callback] callback function invoked after parsing
73009   */
73010  fabric.Line.fromElement = function(element, callback, options) {
73011    options = options || { };
73012    var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES),
73013        points = [
73014          parsedAttributes.x1 || 0,
73015          parsedAttributes.y1 || 0,
73016          parsedAttributes.x2 || 0,
73017          parsedAttributes.y2 || 0
73018        ];
73019    callback(new fabric.Line(points, extend(parsedAttributes, options)));
73020  };
73021  /* _FROM_SVG_END_ */
73022
73023  /**
73024   * Returns fabric.Line instance from an object representation
73025   * @static
73026   * @memberOf fabric.Line
73027   * @param {Object} object Object to create an instance from
73028   * @param {function} [callback] invoked with new instance as first argument
73029   */
73030  fabric.Line.fromObject = function(object, callback) {
73031    function _callback(instance) {
73032      delete instance.points;
73033      callback && callback(instance);
73034    };
73035    var options = clone(object, true);
73036    options.points = [object.x1, object.y1, object.x2, object.y2];
73037    fabric.Object._fromObject('Line', options, _callback, 'points');
73038  };
73039
73040  /**
73041   * Produces a function that calculates distance from canvas edge to Line origin.
73042   */
73043  function makeEdgeToOriginGetter(propertyNames, originValues) {
73044    var origin = propertyNames.origin,
73045        axis1 = propertyNames.axis1,
73046        axis2 = propertyNames.axis2,
73047        dimension = propertyNames.dimension,
73048        nearest = originValues.nearest,
73049        center = originValues.center,
73050        farthest = originValues.farthest;
73051
73052    return function() {
73053      switch (this.get(origin)) {
73054        case nearest:
73055          return Math.min(this.get(axis1), this.get(axis2));
73056        case center:
73057          return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension));
73058        case farthest:
73059          return Math.max(this.get(axis1), this.get(axis2));
73060      }
73061    };
73062
73063  }
73064
73065})( true ? exports : 
73065this
vendor: 5,929 bytes, lines 73065-73274
73065);
73066
73067
73068(function(global) {
73069
73070  'use strict';
73071
73072  var fabric = global.fabric || (global.fabric = { }),
73073      pi = Math.PI;
73074
73075  if (fabric.Circle) {
73076    fabric.warn('fabric.Circle is already defined.');
73077    return;
73078  }
73079
73080  /**
73081   * Circle class
73082   * @class fabric.Circle
73083   * @extends fabric.Object
73084   * @see {@link fabric.Circle#initialize} for constructor definition
73085   */
73086  fabric.Circle = fabric.util.createClass(fabric.Object, /** @lends fabric.Circle.prototype */ {
73087
73088    /**
73089     * Type of an object
73090     * @type String
73091     * @default
73092     */
73093    type: 'circle',
73094
73095    /**
73096     * Radius of this circle
73097     * @type Number
73098     * @default
73099     */
73100    radius: 0,
73101
73102    /**
73103     * Start angle of the circle, moving clockwise
73104     * deprecated type, this should be in degree, this was an oversight.
73105     * probably will change to degrees in next major version
73106     * @type Number
73107     * @default 0
73108     */
73109    startAngle: 0,
73110
73111    /**
73112     * End angle of the circle
73113     * deprecated type, this should be in degree, this was an oversight.
73114     * probably will change to degrees in next major version
73115     * @type Number
73116     * @default 2Pi
73117     */
73118    endAngle: pi * 2,
73119
73120    cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius', 'startAngle', 'endAngle'),
73121
73122    /**
73123     * @private
73124     * @param {String} key
73125     * @param {*} value
73126     * @return {fabric.Circle} thisArg
73127     */
73128    _set: function(key, value) {
73129      this.callSuper('_set', key, value);
73130
73131      if (key === 'radius') {
73132        this.setRadius(value);
73133      }
73134
73135      return this;
73136    },
73137
73138    /**
73139     * Returns object representation of an instance
73140     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
73141     * @return {Object} object representation of an instance
73142     */
73143    toObject: function(propertiesToInclude) {
73144      return this.callSuper('toObject', ['radius', 'startAngle', 'endAngle'].concat(propertiesToInclude));
73145    },
73146
73147    /* _TO_SVG_START_ */
73148
73149    /**
73150     * Returns svg representation of an instance
73151     * @return {Array} an array of strings with the specific svg representation
73152     * of the instance
73153     */
73154    _toSVG: function() {
73155      var svgString, x = 0, y = 0,
73156          angle = (this.endAngle - this.startAngle) % ( 2 * pi);
73157
73158      if (angle === 0) {
73159        svgString = [
73160          '<circle ', 'COMMON_PARTS',
73161          'cx="' + x + '" cy="' + y + '" ',
73162          'r="', this.radius,
73163          '" />\n'
73164        ];
73165      }
73166      else {
73167        var startX = fabric.util.cos(this.startAngle) * this.radius,
73168            startY = fabric.util.sin(this.startAngle) * this.radius,
73169            endX = fabric.util.cos(this.endAngle) * this.radius,
73170            endY = fabric.util.sin(this.endAngle) * this.radius,
73171            largeFlag = angle > pi ? '1' : '0';
73172        svgString = [
73173          '<path d="M ' + startX + ' ' + startY,
73174          ' A ' + this.radius + ' ' + this.radius,
73175          ' 0 ', +largeFlag + ' 1', ' ' + endX + ' ' + endY,
73176          '" ', 'COMMON_PARTS', ' />\n'
73177        ];
73178      }
73179      return svgString;
73180    },
73181    /* _TO_SVG_END_ */
73182
73183    /**
73184     * @private
73185     * @param {CanvasRenderingContext2D} ctx context to render on
73186     */
73187    _render: function(ctx) {
73188      ctx.beginPath();
73189      ctx.arc(
73190        0,
73191        0,
73192        this.radius,
73193        this.startAngle,
73194        this.endAngle, false);
73195      this._renderPaintInOrder(ctx);
73196    },
73197
73198    /**
73199     * Returns horizontal radius of an object (according to how an object is scaled)
73200     * @return {Number}
73201     */
73202    getRadiusX: function() {
73203      return this.get('radius') * this.get('scaleX');
73204    },
73205
73206    /**
73207     * Returns vertical radius of an object (according to how an object is scaled)
73208     * @return {Number}
73209     */
73210    getRadiusY: function() {
73211      return this.get('radius') * this.get('scaleY');
73212    },
73213
73214    /**
73215     * Sets radius of an object (and updates width accordingly)
73216     * @return {fabric.Circle} thisArg
73217     */
73218    setRadius: function(value) {
73219      this.radius = value;
73220      return this.set('width', value * 2).set('height', value * 2);
73221    },
73222  });
73223
73224  /* _FROM_SVG_START_ */
73225  /**
73226   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement})
73227   * @static
73228   * @memberOf fabric.Circle
73229   * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement
73230   */
73231  fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' '));
73232
73233  /**
73234   * Returns {@link fabric.Circle} instance from an SVG element
73235   * @static
73236   * @memberOf fabric.Circle
73237   * @param {SVGElement} element Element to parse
73238   * @param {Function} [callback] Options callback invoked after parsing is finished
73239   * @param {Object} [options] Options object
73240   * @throws {Error} If value of `r` attribute is missing or invalid
73241   */
73242  fabric.Circle.fromElement = function(element, callback) {
73243    var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);
73244
73245    if (!isValidRadius(parsedAttributes)) {
73246      throw new Error('value of `r` attribute is required and can not be negative');
73247    }
73248
73249    parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.radius;
73250    parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius;
73251    callback(new fabric.Circle(parsedAttributes));
73252  };
73253
73254  /**
73255   * @private
73256   */
73257  function isValidRadius(attributes) {
73258    return (('radius' in attributes) && (attributes.radius >= 0));
73259  }
73260  /* _FROM_SVG_END_ */
73261
73262  /**
73263   * Returns {@link fabric.Circle} instance from an object representation
73264   * @static
73265   * @memberOf fabric.Circle
73266   * @param {Object} object Object to create an instance from
73267   * @param {function} [callback] invoked with new instance as first argument
73268   * @return {void}
73269   */
73270  fabric.Circle.fromObject = function(object, callback) {
73271    fabric.Object._fromObject('Circle', object, callback);
73272  };
73273
73274})( true ? exports : 
73274this);
73275
73276
73277(function(global) {
73278
73279  'use strict';
73280
73281  var fabric = global.fabric || (global.fabric = { });
73282
73283  if (fabric.Triangle) {
73284    fabric.warn('fabric.Triangle is already defined');
73285    return;
73286  }
73287
73288  /**
73289   * Triangle class
73290   * @class fabric.Triangle
73291   * @extends fabric.Object
73292   * @return {fabric.Triangle} thisArg
73293   * @see {@link fabric.Triangle#initialize} for constructor definition
73294   */
73295  fabric.Triangle = fabric.util.createClass(fabric.Object, /** @lends fabric.Triangle.prototype */ {
73296
73297    /**
73298     * Type of an object
vendor: 12,179 bytes, lines 73299-73741
73299     * @type String
73300     * @default
73301     */
73302    type: 'triangle',
73303
73304    /**
73305     * Width is set to 100 to compensate the old initialize code that was setting it to 100
73306     * @type Number
73307     * @default
73308     */
73309    width: 100,
73310
73311    /**
73312     * Height is set to 100 to compensate the old initialize code that was setting it to 100
73313     * @type Number
73314     * @default
73315     */
73316    height: 100,
73317
73318    /**
73319     * @private
73320     * @param {CanvasRenderingContext2D} ctx Context to render on
73321     */
73322    _render: function(ctx) {
73323      var widthBy2 = this.width / 2,
73324          heightBy2 = this.height / 2;
73325
73326      ctx.beginPath();
73327      ctx.moveTo(-widthBy2, heightBy2);
73328      ctx.lineTo(0, -heightBy2);
73329      ctx.lineTo(widthBy2, heightBy2);
73330      ctx.closePath();
73331
73332      this._renderPaintInOrder(ctx);
73333    },
73334
73335    /* _TO_SVG_START_ */
73336    /**
73337     * Returns svg representation of an instance
73338     * @return {Array} an array of strings with the specific svg representation
73339     * of the instance
73340     */
73341    _toSVG: function() {
73342      var widthBy2 = this.width / 2,
73343          heightBy2 = this.height / 2,
73344          points = [
73345            -widthBy2 + ' ' + heightBy2,
73346            '0 ' + -heightBy2,
73347            widthBy2 + ' ' + heightBy2
73348          ].join(',');
73349      return [
73350        '<polygon ', 'COMMON_PARTS',
73351        'points="', points,
73352        '" />'
73353      ];
73354    },
73355    /* _TO_SVG_END_ */
73356  });
73357
73358  /**
73359   * Returns {@link fabric.Triangle} instance from an object representation
73360   * @static
73361   * @memberOf fabric.Triangle
73362   * @param {Object} object Object to create an instance from
73363   * @param {function} [callback] invoked with new instance as first argument
73364   */
73365  fabric.Triangle.fromObject = function(object, callback) {
73366    return fabric.Object._fromObject('Triangle', object, callback);
73367  };
73368
73369})( true ? exports : this);
73370
73371
73372(function(global) {
73373
73374  'use strict';
73375
73376  var fabric = global.fabric || (global.fabric = { }),
73377      piBy2   = Math.PI * 2;
73378
73379  if (fabric.Ellipse) {
73380    fabric.warn('fabric.Ellipse is already defined.');
73381    return;
73382  }
73383
73384  /**
73385   * Ellipse class
73386   * @class fabric.Ellipse
73387   * @extends fabric.Object
73388   * @return {fabric.Ellipse} thisArg
73389   * @see {@link fabric.Ellipse#initialize} for constructor definition
73390   */
73391  fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @lends fabric.Ellipse.prototype */ {
73392
73393    /**
73394     * Type of an object
73395     * @type String
73396     * @default
73397     */
73398    type: 'ellipse',
73399
73400    /**
73401     * Horizontal radius
73402     * @type Number
73403     * @default
73404     */
73405    rx:   0,
73406
73407    /**
73408     * Vertical radius
73409     * @type Number
73410     * @default
73411     */
73412    ry:   0,
73413
73414    cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),
73415
73416    /**
73417     * Constructor
73418     * @param {Object} [options] Options object
73419     * @return {fabric.Ellipse} thisArg
73420     */
73421    initialize: function(options) {
73422      this.callSuper('initialize', options);
73423      this.set('rx', options && options.rx || 0);
73424      this.set('ry', options && options.ry || 0);
73425    },
73426
73427    /**
73428     * @private
73429     * @param {String} key
73430     * @param {*} value
73431     * @return {fabric.Ellipse} thisArg
73432     */
73433    _set: function(key, value) {
73434      this.callSuper('_set', key, value);
73435      switch (key) {
73436
73437        case 'rx':
73438          this.rx = value;
73439          this.set('width', value * 2);
73440          break;
73441
73442        case 'ry':
73443          this.ry = value;
73444          this.set('height', value * 2);
73445          break;
73446
73447      }
73448      return this;
73449    },
73450
73451    /**
73452     * Returns horizontal radius of an object (according to how an object is scaled)
73453     * @return {Number}
73454     */
73455    getRx: function() {
73456      return this.get('rx') * this.get('scaleX');
73457    },
73458
73459    /**
73460     * Returns Vertical radius of an object (according to how an object is scaled)
73461     * @return {Number}
73462     */
73463    getRy: function() {
73464      return this.get('ry') * this.get('scaleY');
73465    },
73466
73467    /**
73468     * Returns object representation of an instance
73469     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
73470     * @return {Object} object representation of an instance
73471     */
73472    toObject: function(propertiesToInclude) {
73473      return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));
73474    },
73475
73476    /* _TO_SVG_START_ */
73477    /**
73478     * Returns svg representation of an instance
73479     * @return {Array} an array of strings with the specific svg representation
73480     * of the instance
73481     */
73482    _toSVG: function() {
73483      return [
73484        '<ellipse ', 'COMMON_PARTS',
73485        'cx="0" cy="0" ',
73486        'rx="', this.rx,
73487        '" ry="', this.ry,
73488        '" />\n'
73489      ];
73490    },
73491    /* _TO_SVG_END_ */
73492
73493    /**
73494     * @private
73495     * @param {CanvasRenderingContext2D} ctx context to render on
73496     */
73497    _render: function(ctx) {
73498      ctx.beginPath();
73499      ctx.save();
73500      ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);
73501      ctx.arc(
73502        0,
73503        0,
73504        this.rx,
73505        0,
73506        piBy2,
73507        false);
73508      ctx.restore();
73509      this._renderPaintInOrder(ctx);
73510    },
73511  });
73512
73513  /* _FROM_SVG_START_ */
73514  /**
73515   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement})
73516   * @static
73517   * @memberOf fabric.Ellipse
73518   * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement
73519   */
73520  fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' '));
73521
73522  /**
73523   * Returns {@link fabric.Ellipse} instance from an SVG element
73524   * @static
73525   * @memberOf fabric.Ellipse
73526   * @param {SVGElement} element Element to parse
73527   * @param {Function} [callback] Options callback invoked after parsing is finished
73528   * @return {fabric.Ellipse}
73529   */
73530  fabric.Ellipse.fromElement = function(element, callback) {
73531
73532    var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES);
73533
73534    parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx;
73535    parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry;
73536    callback(new fabric.Ellipse(parsedAttributes));
73537  };
73538  /* _FROM_SVG_END_ */
73539
73540  /**
73541   * Returns {@link fabric.Ellipse} instance from an object representation
73542   * @static
73543   * @memberOf fabric.Ellipse
73544   * @param {Object} object Object to create an instance from
73545   * @param {function} [callback] invoked with new instance as first argument
73546   * @return {void}
73547   */
73548  fabric.Ellipse.fromObject = function(object, callback) {
73549    fabric.Object._fromObject('Ellipse', object, callback);
73550  };
73551
73552})( true ? exports : this);
73553
73554
73555(function(global) {
73556
73557  'use strict';
73558
73559  var fabric = global.fabric || (global.fabric = { }),
73560      extend = fabric.util.object.extend;
73561
73562  if (fabric.Rect) {
73563    fabric.warn('fabric.Rect is already defined');
73564    return;
73565  }
73566
73567  /**
73568   * Rectangle class
73569   * @class fabric.Rect
73570   * @extends fabric.Object
73571   * @return {fabric.Rect} thisArg
73572   * @see {@link fabric.Rect#initialize} for constructor definition
73573   */
73574  fabric.Rect = fabric.util.createClass(fabric.Object, /** @lends fabric.Rect.prototype */ {
73575
73576    /**
73577     * List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged})
73578     * as well as for history (undo/redo) purposes
73579     * @type Array
73580     */
73581    stateProperties: fabric.Object.prototype.stateProperties.concat('rx', 'ry'),
73582
73583    /**
73584     * Type of an object
73585     * @type String
73586     * @default
73587     */
73588    type: 'rect',
73589
73590    /**
73591     * Horizontal border radius
73592     * @type Number
73593     * @default
73594     */
73595    rx:   0,
73596
73597    /**
73598     * Vertical border radius
73599     * @type Number
73600     * @default
73601     */
73602    ry:   0,
73603
73604    cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),
73605
73606    /**
73607     * Constructor
73608     * @param {Object} [options] Options object
73609     * @return {Object} thisArg
73610     */
73611    initialize: function(options) {
73612      this.callSuper('initialize', options);
73613      this._initRxRy();
73614    },
73615
73616    /**
73617     * Initializes rx/ry attributes
73618     * @private
73619     */
73620    _initRxRy: function() {
73621      if (this.rx && !this.ry) {
73622        this.ry = this.rx;
73623      }
73624      else if (this.ry && !this.rx) {
73625        this.rx = this.ry;
73626      }
73627    },
73628
73629    /**
73630     * @private
73631     * @param {CanvasRenderingContext2D} ctx Context to render on
73632     */
73633    _render: function(ctx) {
73634
73635      // 1x1 case (used in spray brush) optimization was removed because
73636      // with caching and higher zoom level this makes more damage than help
73637
73638      var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0,
73639          ry = this.ry ? Math.min(this.ry, this.height / 2) : 0,
73640          w = this.width,
73641          h = this.height,
73642          x = -this.width / 2,
73643          y = -this.height / 2,
73644          isRounded = rx !== 0 || ry !== 0,
73645          /* "magic number" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */
73646          k = 1 - 0.5522847498;
73647      ctx.beginPath();
73648
73649      ctx.moveTo(x + rx, y);
73650
73651      ctx.lineTo(x + w - rx, y);
73652      isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry);
73653
73654      ctx.lineTo(x + w, y + h - ry);
73655      isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h);
73656
73657      ctx.lineTo(x + rx, y + h);
73658      isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry);
73659
73660      ctx.lineTo(x, y + ry);
73661      isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);
73662
73663      ctx.closePath();
73664
73665      this._renderPaintInOrder(ctx);
73666    },
73667
73668    /**
73669     * Returns object representation of an instance
73670     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
73671     * @return {Object} object representation of an instance
73672     */
73673    toObject: function(propertiesToInclude) {
73674      return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));
73675    },
73676
73677    /* _TO_SVG_START_ */
73678    /**
73679     * Returns svg representation of an instance
73680     * @return {Array} an array of strings with the specific svg representation
73681     * of the instance
73682     */
73683    _toSVG: function() {
73684      var x = -this.width / 2, y = -this.height / 2;
73685      return [
73686        '<rect ', 'COMMON_PARTS',
73687        'x="', x, '" y="', y,
73688        '" rx="', this.rx, '" ry="', this.ry,
73689        '" width="', this.width, '" height="', this.height,
73690        '" />\n'
73691      ];
73692    },
73693    /* _TO_SVG_END_ */
73694  });
73695
73696  /* _FROM_SVG_START_ */
73697  /**
73698   * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`)
73699   * @static
73700   * @memberOf fabric.Rect
73701   * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement
73702   */
73703  fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' '));
73704
73705  /**
73706   * Returns {@link fabric.Rect} instance from an SVG element
73707   * @static
73708   * @memberOf fabric.Rect
73709   * @param {SVGElement} element Element to parse
73710   * @param {Function} callback callback function invoked after parsing
73711   * @param {Object} [options] Options object
73712   */
73713  fabric.Rect.fromElement = function(element, callback, options) {
73714    if (!element) {
73715      return callback(null);
73716    }
73717    options = options || { };
73718
73719    var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES);
73720    parsedAttributes.left = parsedAttributes.left || 0;
73721    parsedAttributes.top  = parsedAttributes.top  || 0;
73722    parsedAttributes.height  = parsedAttributes.height || 0;
73723    parsedAttributes.width  = parsedAttributes.width || 0;
73724    var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));
73725    rect.visible = rect.visible && rect.width > 0 && rect.height > 0;
73726    callback(rect);
73727  };
73728  /* _FROM_SVG_END_ */
73729
73730  /**
73731   * Returns {@link fabric.Rect} instance from an object representation
73732   * @static
73733   * @memberOf fabric.Rect
73734   * @param {Object} object Object to create an instance from
73735   * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created
73736   */
73737  fabric.Rect.fromObject = function(object, callback) {
73738    return fabric.Object._fromObject('Rect', object, callback);
73739  };
73740
73741})( true ? exports : this
vendor: 7,398 bytes, lines 73741-73987
73741);
73742
73743
73744(function(global) {
73745
73746  'use strict';
73747
73748  var fabric = global.fabric || (global.fabric = { }),
73749      extend = fabric.util.object.extend,
73750      min = fabric.util.array.min,
73751      max = fabric.util.array.max,
73752      toFixed = fabric.util.toFixed;
73753
73754  if (fabric.Polyline) {
73755    fabric.warn('fabric.Polyline is already defined');
73756    return;
73757  }
73758
73759  /**
73760   * Polyline class
73761   * @class fabric.Polyline
73762   * @extends fabric.Object
73763   * @see {@link fabric.Polyline#initialize} for constructor definition
73764   */
73765  fabric.Polyline = fabric.util.createClass(fabric.Object, /** @lends fabric.Polyline.prototype */ {
73766
73767    /**
73768     * Type of an object
73769     * @type String
73770     * @default
73771     */
73772    type: 'polyline',
73773
73774    /**
73775     * Points array
73776     * @type Array
73777     * @default
73778     */
73779    points: null,
73780
73781    cacheProperties: fabric.Object.prototype.cacheProperties.concat('points'),
73782
73783    /**
73784     * Constructor
73785     * @param {Array} points Array of points (where each point is an object with x and y)
73786     * @param {Object} [options] Options object
73787     * @return {fabric.Polyline} thisArg
73788     * @example
73789     * var poly = new fabric.Polyline([
73790     *     { x: 10, y: 10 },
73791     *     { x: 50, y: 30 },
73792     *     { x: 40, y: 70 },
73793     *     { x: 60, y: 50 },
73794     *     { x: 100, y: 150 },
73795     *     { x: 40, y: 100 }
73796     *   ], {
73797     *   stroke: 'red',
73798     *   left: 100,
73799     *   top: 100
73800     * });
73801     */
73802    initialize: function(points, options) {
73803      options = options || {};
73804      this.points = points || [];
73805      this.callSuper('initialize', options);
73806      this._setPositionDimensions(options);
73807    },
73808
73809    _setPositionDimensions: function(options) {
73810      var calcDim = this._calcDimensions(options), correctLeftTop;
73811      this.width = calcDim.width;
73812      this.height = calcDim.height;
73813      if (!options.fromSVG) {
73814        correctLeftTop = this.translateToGivenOrigin(
73815          { x: calcDim.left - this.strokeWidth / 2, y: calcDim.top - this.strokeWidth / 2 },
73816          'left',
73817          'top',
73818          this.originX,
73819          this.originY
73820        );
73821      }
73822      if (typeof options.left === 'undefined') {
73823        this.left = options.fromSVG ? calcDim.left : correctLeftTop.x;
73824      }
73825      if (typeof options.top === 'undefined') {
73826        this.top = options.fromSVG ? calcDim.top : correctLeftTop.y;
73827      }
73828      this.pathOffset = {
73829        x: calcDim.left + this.width / 2,
73830        y: calcDim.top + this.height / 2
73831      };
73832    },
73833
73834    /**
73835     * Calculate the polygon min and max point from points array,
73836     * returning an object with left, top, width, height to measure the
73837     * polygon size
73838     * @return {Object} object.left X coordinate of the polygon leftmost point
73839     * @return {Object} object.top Y coordinate of the polygon topmost point
73840     * @return {Object} object.width distance between X coordinates of the polygon leftmost and rightmost point
73841     * @return {Object} object.height distance between Y coordinates of the polygon topmost and bottommost point
73842     * @private
73843     */
73844    _calcDimensions: function() {
73845
73846      var points = this.points,
73847          minX = min(points, 'x') || 0,
73848          minY = min(points, 'y') || 0,
73849          maxX = max(points, 'x') || 0,
73850          maxY = max(points, 'y') || 0,
73851          width = (maxX - minX),
73852          height = (maxY - minY);
73853
73854      return {
73855        left: minX,
73856        top: minY,
73857        width: width,
73858        height: height
73859      };
73860    },
73861
73862    /**
73863     * Returns object representation of an instance
73864     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
73865     * @return {Object} Object representation of an instance
73866     */
73867    toObject: function(propertiesToInclude) {
73868      return extend(this.callSuper('toObject', propertiesToInclude), {
73869        points: this.points.concat()
73870      });
73871    },
73872
73873    /* _TO_SVG_START_ */
73874    /**
73875     * Returns svg representation of an instance
73876     * @return {Array} an array of strings with the specific svg representation
73877     * of the instance
73878     */
73879    _toSVG: function() {
73880      var points = [], diffX = this.pathOffset.x, diffY = this.pathOffset.y,
73881          NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;
73882
73883      for (var i = 0, len = this.points.length; i < len; i++) {
73884        points.push(
73885          toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',',
73886          toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' '
73887        );
73888      }
73889      return [
73890        '<' + this.type + ' ', 'COMMON_PARTS',
73891        'points="', points.join(''),
73892        '" />\n'
73893      ];
73894    },
73895    /* _TO_SVG_END_ */
73896
73897
73898    /**
73899     * @private
73900     * @param {CanvasRenderingContext2D} ctx Context to render on
73901     */
73902    commonRender: function(ctx) {
73903      var point, len = this.points.length,
73904          x = this.pathOffset.x,
73905          y = this.pathOffset.y;
73906
73907      if (!len || isNaN(this.points[len - 1].y)) {
73908        // do not draw if no points or odd points
73909        // NaN comes from parseFloat of a empty string in parser
73910        return false;
73911      }
73912      ctx.beginPath();
73913      ctx.moveTo(this.points[0].x - x, this.points[0].y - y);
73914      for (var i = 0; i < len; i++) {
73915        point = this.points[i];
73916        ctx.lineTo(point.x - x, point.y - y);
73917      }
73918      return true;
73919    },
73920
73921    /**
73922     * @private
73923     * @param {CanvasRenderingContext2D} ctx Context to render on
73924     */
73925    _render: function(ctx) {
73926      if (!this.commonRender(ctx)) {
73927        return;
73928      }
73929      this._renderPaintInOrder(ctx);
73930    },
73931
73932    /**
73933     * Returns complexity of an instance
73934     * @return {Number} complexity of this instance
73935     */
73936    complexity: function() {
73937      return this.get('points').length;
73938    }
73939  });
73940
73941  /* _FROM_SVG_START_ */
73942  /**
73943   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement})
73944   * @static
73945   * @memberOf fabric.Polyline
73946   * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement
73947   */
73948  fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();
73949
73950  /**
73951   * Returns fabric.Polyline instance from an SVG element
73952   * @static
73953   * @memberOf fabric.Polyline
73954   * @param {SVGElement} element Element to parser
73955   * @param {Function} callback callback function invoked after parsing
73956   * @param {Object} [options] Options object
73957   */
73958  fabric.Polyline.fromElementGenerator = function(_class) {
73959    return function(element, callback, options) {
73960      if (!element) {
73961        return callback(null);
73962      }
73963      options || (options = { });
73964
73965      var points = fabric.parsePointsAttribute(element.getAttribute('points')),
73966          parsedAttributes = fabric.parseAttributes(element, fabric[_class].ATTRIBUTE_NAMES);
73967      parsedAttributes.fromSVG = true;
73968      callback(new fabric[_class](points, extend(parsedAttributes, options)));
73969    };
73970  };
73971
73972  fabric.Polyline.fromElement = fabric.Polyline.fromElementGenerator('Polyline');
73973
73974  /* _FROM_SVG_END_ */
73975
73976  /**
73977   * Returns fabric.Polyline instance from an object representation
73978   * @static
73979   * @memberOf fabric.Polyline
73980   * @param {Object} object Object to create an instance from
73981   * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created
73982   */
73983  fabric.Polyline.fromObject = function(object, callback) {
73984    return fabric.Object._fromObject('Polyline', object, callback, 'points');
73985  };
73986
73987})( true ? exports : 
73987this);
73988
73989
73990(function(global) {
73991
73992  'use strict';
73993
73994  var fabric = global.fabric || (global.fabric = { });
73995
73996  if (fabric.Polygon) {
73997    fabric.warn('fabric.Polygon is already defined');
73998    return;
73999  }
74000
74001  /**
74002   * Polygon class
74003   * @class fabric.Polygon
74004   * @extends fabric.Polyline
74005   * @see {@link fabric.Polygon#initialize} for constructor definition
74006   */
74007  fabric.Polygon = fabric.util.createClass(fabric.Polyline, /** @lends fabric.Polygon.prototype */ {
74008
74009    /**
74010     * Type of an object
74011     * @type String
74012     * @default
74013     */
74014    type: 'polygon',
74015
74016    /**
74017     * @private
74018     * @param {CanvasRenderingContext2D} ctx Context to render on
74019     */
74020    _render: function(ctx) {
74021      if (!this.commonRender(ctx)) {
74022        return;
74023      }
74024      ctx.closePath();
74025      this._renderPaintInOrder(ctx);
74026    },
74027
74028  });
74029
74030  /* _FROM_SVG_START_ */
74031  /**
74032   * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`)
74033   * @static
74034   * @memberOf fabric.Polygon
74035   * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement
74036   */
74037  fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();
74038
74039  /**
74040   * Returns {@link fabric.Polygon} instance from an SVG element
74041   * @static
74042   * @memberOf fabric.Polygon
74043   * @param {SVGElement} element Element to parse
74044   * @param {Function} callback callback function invoked after parsing
74045   * @param {Object} [options] Options object
74046   */
74047  fabric.Polygon.fromElement = fabric.Polyline.fromElementGenerator('Polygon');
74048  /* _FROM_SVG_END_ */
74049
74050  /**
74051   * Returns fabric.Polygon instance from an object representation
74052   * @static
74053   * @memberOf fabric.Polygon
74054   * @param {Object} object Object to create an instance from
74055   * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created
74056   * @return {void}
74057   */
74058  fabric.Polygon.fromObject = function(object, callback) {
74059    fabric.Object._fromObject('Polygon', object, callback, 'points');
74060  };
74061
74062})( true ? exports : this
vendor: 10,623 bytes, lines 74062-74439
74062);
74063
74064
74065(function(global) {
74066
74067  'use strict';
74068
74069  var fabric = global.fabric || (global.fabric = { }),
74070      min = fabric.util.array.min,
74071      max = fabric.util.array.max,
74072      extend = fabric.util.object.extend,
74073      _toString = Object.prototype.toString,
74074      toFixed = fabric.util.toFixed;
74075
74076  if (fabric.Path) {
74077    fabric.warn('fabric.Path is already defined');
74078    return;
74079  }
74080
74081  /**
74082   * Path class
74083   * @class fabric.Path
74084   * @extends fabric.Object
74085   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup}
74086   * @see {@link fabric.Path#initialize} for constructor definition
74087   */
74088  fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ {
74089
74090    /**
74091     * Type of an object
74092     * @type String
74093     * @default
74094     */
74095    type: 'path',
74096
74097    /**
74098     * Array of path points
74099     * @type Array
74100     * @default
74101     */
74102    path: null,
74103
74104    cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'),
74105
74106    stateProperties: fabric.Object.prototype.stateProperties.concat('path'),
74107
74108    /**
74109     * Constructor
74110     * @param {Array|String} path Path data (sequence of coordinates and corresponding "command" tokens)
74111     * @param {Object} [options] Options object
74112     * @return {fabric.Path} thisArg
74113     */
74114    initialize: function(path, options) {
74115      options = options || { };
74116      this.callSuper('initialize', options);
74117      if (!path) {
74118        path = [];
74119      }
74120
74121      var fromArray = _toString.call(path) === '[object Array]';
74122
74123      this.path = fabric.util.makePathSimpler(
74124        fromArray ? path : fabric.util.parsePath(path)
74125      );
74126
74127      if (!this.path) {
74128        return;
74129      }
74130      fabric.Polyline.prototype._setPositionDimensions.call(this, options);
74131    },
74132
74133    /**
74134     * @private
74135     * @param {CanvasRenderingContext2D} ctx context to render path on
74136     */
74137    _renderPathCommands: function(ctx) {
74138      var current, // current instruction
74139          subpathStartX = 0,
74140          subpathStartY = 0,
74141          x = 0, // current x
74142          y = 0, // current y
74143          controlX = 0, // current control point x
74144          controlY = 0, // current control point y
74145          l = -this.pathOffset.x,
74146          t = -this.pathOffset.y;
74147
74148      ctx.beginPath();
74149
74150      for (var i = 0, len = this.path.length; i < len; ++i) {
74151
74152        current = this.path[i];
74153
74154        switch (current[0]) { // first letter
74155
74156          case 'L': // lineto, absolute
74157            x = current[1];
74158            y = current[2];
74159            ctx.lineTo(x + l, y + t);
74160            break;
74161
74162          case 'M': // moveTo, absolute
74163            x = current[1];
74164            y = current[2];
74165            subpathStartX = x;
74166            subpathStartY = y;
74167            ctx.moveTo(x + l, y + t);
74168            break;
74169
74170          case 'C': // bezierCurveTo, absolute
74171            x = current[5];
74172            y = current[6];
74173            controlX = current[3];
74174            controlY = current[4];
74175            ctx.bezierCurveTo(
74176              current[1] + l,
74177              current[2] + t,
74178              controlX + l,
74179              controlY + t,
74180              x + l,
74181              y + t
74182            );
74183            break;
74184
74185          case 'Q': // quadraticCurveTo, absolute
74186            ctx.quadraticCurveTo(
74187              current[1] + l,
74188              current[2] + t,
74189              current[3] + l,
74190              current[4] + t
74191            );
74192            x = current[3];
74193            y = current[4];
74194            controlX = current[1];
74195            controlY = current[2];
74196            break;
74197
74198          case 'z':
74199          case 'Z':
74200            x = subpathStartX;
74201            y = subpathStartY;
74202            ctx.closePath();
74203            break;
74204        }
74205      }
74206    },
74207
74208    /**
74209     * @private
74210     * @param {CanvasRenderingContext2D} ctx context to render path on
74211     */
74212    _render: function(ctx) {
74213      this._renderPathCommands(ctx);
74214      this._renderPaintInOrder(ctx);
74215    },
74216
74217    /**
74218     * Returns string representation of an instance
74219     * @return {String} string representation of an instance
74220     */
74221    toString: function() {
74222      return '#<fabric.Path (' + this.complexity() +
74223        '): { "top": ' + this.top + ', "left": ' + this.left + ' }>';
74224    },
74225
74226    /**
74227     * Returns object representation of an instance
74228     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
74229     * @return {Object} object representation of an instance
74230     */
74231    toObject: function(propertiesToInclude) {
74232      return extend(this.callSuper('toObject', propertiesToInclude), {
74233        path: this.path.map(function(item) { return item.slice(); }),
74234      });
74235    },
74236
74237    /**
74238     * Returns dataless object representation of an instance
74239     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
74240     * @return {Object} object representation of an instance
74241     */
74242    toDatalessObject: function(propertiesToInclude) {
74243      var o = this.toObject(['sourcePath'].concat(propertiesToInclude));
74244      if (o.sourcePath) {
74245        delete o.path;
74246      }
74247      return o;
74248    },
74249
74250    /* _TO_SVG_START_ */
74251    /**
74252     * Returns svg representation of an instance
74253     * @return {Array} an array of strings with the specific svg representation
74254     * of the instance
74255     */
74256    _toSVG: function() {
74257      var path = fabric.util.joinPath(this.path);
74258      return [
74259        '<path ', 'COMMON_PARTS',
74260        'd="', path,
74261        '" stroke-linecap="round" ',
74262        '/>\n'
74263      ];
74264    },
74265
74266    _getOffsetTransform: function() {
74267      var digits = fabric.Object.NUM_FRACTION_DIGITS;
74268      return ' translate(' + toFixed(-this.pathOffset.x, digits) + ', ' +
74269          toFixed(-this.pathOffset.y, digits) + ')';
74270    },
74271
74272    /**
74273     * Returns svg clipPath representation of an instance
74274     * @param {Function} [reviver] Method for further parsing of svg representation.
74275     * @return {String} svg representation of an instance
74276     */
74277    toClipPathSVG: function(reviver) {
74278      var additionalTransform = this._getOffsetTransform();
74279      return '\t' + this._createBaseClipPathSVGMarkup(
74280        this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform }
74281      );
74282    },
74283
74284    /**
74285     * Returns svg representation of an instance
74286     * @param {Function} [reviver] Method for further parsing of svg representation.
74287     * @return {String} svg representation of an instance
74288     */
74289    toSVG: function(reviver) {
74290      var additionalTransform = this._getOffsetTransform();
74291      return this._createBaseSVGMarkup(this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform  });
74292    },
74293    /* _TO_SVG_END_ */
74294
74295    /**
74296     * Returns number representation of an instance complexity
74297     * @return {Number} complexity of this instance
74298     */
74299    complexity: function() {
74300      return this.path.length;
74301    },
74302
74303    /**
74304     * @private
74305     */
74306    _calcDimensions: function() {
74307
74308      var aX = [],
74309          aY = [],
74310          current, // current instruction
74311          subpathStartX = 0,
74312          subpathStartY = 0,
74313          x = 0, // current x
74314          y = 0, // current y
74315          bounds;
74316
74317      for (var i = 0, len = this.path.length; i < len; ++i) {
74318
74319        current = this.path[i];
74320
74321        switch (current[0]) { // first letter
74322
74323          case 'L': // lineto, absolute
74324            x = current[1];
74325            y = current[2];
74326            bounds = [];
74327            break;
74328
74329          case 'M': // moveTo, absolute
74330            x = current[1];
74331            y = current[2];
74332            subpathStartX = x;
74333            subpathStartY = y;
74334            bounds = [];
74335            break;
74336
74337          case 'C': // bezierCurveTo, absolute
74338            bounds = fabric.util.getBoundsOfCurve(x, y,
74339              current[1],
74340              current[2],
74341              current[3],
74342              current[4],
74343              current[5],
74344              current[6]
74345            );
74346            x = current[5];
74347            y = current[6];
74348            break;
74349
74350          case 'Q': // quadraticCurveTo, absolute
74351            bounds = fabric.util.getBoundsOfCurve(x, y,
74352              current[1],
74353              current[2],
74354              current[1],
74355              current[2],
74356              current[3],
74357              current[4]
74358            );
74359            x = current[3];
74360            y = current[4];
74361            break;
74362
74363          case 'z':
74364          case 'Z':
74365            x = subpathStartX;
74366            y = subpathStartY;
74367            break;
74368        }
74369        bounds.forEach(function (point) {
74370          aX.push(point.x);
74371          aY.push(point.y);
74372        });
74373        aX.push(x);
74374        aY.push(y);
74375      }
74376
74377      var minX = min(aX) || 0,
74378          minY = min(aY) || 0,
74379          maxX = max(aX) || 0,
74380          maxY = max(aY) || 0,
74381          deltaX = maxX - minX,
74382          deltaY = maxY - minY;
74383
74384      return {
74385        left: minX,
74386        top: minY,
74387        width: deltaX,
74388        height: deltaY
74389      };
74390    }
74391  });
74392
74393  /**
74394   * Creates an instance of fabric.Path from an object
74395   * @static
74396   * @memberOf fabric.Path
74397   * @param {Object} object
74398   * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created
74399   */
74400  fabric.Path.fromObject = function(object, callback) {
74401    if (typeof object.sourcePath === 'string') {
74402      var pathUrl = object.sourcePath;
74403      fabric.loadSVGFromURL(pathUrl, function (elements) {
74404        var path = elements[0];
74405        path.setOptions(object);
74406        callback && callback(path);
74407      });
74408    }
74409    else {
74410      fabric.Object._fromObject('Path', object, callback, 'path');
74411    }
74412  };
74413
74414  /* _FROM_SVG_START_ */
74415  /**
74416   * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`)
74417   * @static
74418   * @memberOf fabric.Path
74419   * @see http://www.w3.org/TR/SVG/paths.html#PathElement
74420   */
74421  fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']);
74422
74423  /**
74424   * Creates an instance of fabric.Path from an SVG <path> element
74425   * @static
74426   * @memberOf fabric.Path
74427   * @param {SVGElement} element to parse
74428   * @param {Function} callback Callback to invoke when an fabric.Path instance is created
74429   * @param {Object} [options] Options object
74430   * @param {Function} [callback] Options callback invoked after parsing is finished
74431   */
74432  fabric.Path.fromElement = function(element, callback, options) {
74433    var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES);
74434    parsedAttributes.fromSVG = true;
74435    callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options)));
74436  };
74437  /* _FROM_SVG_END_ */
74438
74439})( true ? exports : 
74439this
vendor: 18,315 bytes, lines 74439-75039
74439);
74440
74441
74442(function(global) {
74443
74444  'use strict';
74445
74446  var fabric = global.fabric || (global.fabric = { }),
74447      min = fabric.util.array.min,
74448      max = fabric.util.array.max;
74449
74450  if (fabric.Group) {
74451    return;
74452  }
74453
74454  /**
74455   * Group class
74456   * @class fabric.Group
74457   * @extends fabric.Object
74458   * @mixes fabric.Collection
74459   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}
74460   * @see {@link fabric.Group#initialize} for constructor definition
74461   */
74462  fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ {
74463
74464    /**
74465     * Type of an object
74466     * @type String
74467     * @default
74468     */
74469    type: 'group',
74470
74471    /**
74472     * Width of stroke
74473     * @type Number
74474     * @default
74475     */
74476    strokeWidth: 0,
74477
74478    /**
74479     * Indicates if click, mouseover, mouseout events & hoverCursor should also check for subtargets
74480     * @type Boolean
74481     * @default
74482     */
74483    subTargetCheck: false,
74484
74485    /**
74486     * Groups are container, do not render anything on theyr own, ence no cache properties
74487     * @type Array
74488     * @default
74489     */
74490    cacheProperties: [],
74491
74492    /**
74493     * setOnGroup is a method used for TextBox that is no more used since 2.0.0 The behavior is still
74494     * available setting this boolean to true.
74495     * @type Boolean
74496     * @since 2.0.0
74497     * @default
74498     */
74499    useSetOnGroup: false,
74500
74501    /**
74502     * Constructor
74503     * @param {Object} objects Group objects
74504     * @param {Object} [options] Options object
74505     * @param {Boolean} [isAlreadyGrouped] if true, objects have been grouped already.
74506     * @return {Object} thisArg
74507     */
74508    initialize: function(objects, options, isAlreadyGrouped) {
74509      options = options || {};
74510      this._objects = [];
74511      // if objects enclosed in a group have been grouped already,
74512      // we cannot change properties of objects.
74513      // Thus we need to set options to group without objects,
74514      isAlreadyGrouped && this.callSuper('initialize', options);
74515      this._objects = objects || [];
74516      for (var i = this._objects.length; i--; ) {
74517        this._objects[i].group = this;
74518      }
74519
74520      if (!isAlreadyGrouped) {
74521        var center = options && options.centerPoint;
74522        // we want to set origins before calculating the bounding box.
74523        // so that the topleft can be set with that in mind.
74524        // if specific top and left are passed, are overwritten later
74525        // with the callSuper('initialize', options)
74526        if (options.originX !== undefined) {
74527          this.originX = options.originX;
74528        }
74529        if (options.originY !== undefined) {
74530          this.originY = options.originY;
74531        }
74532        // if coming from svg i do not want to calc bounds.
74533        // i assume width and height are passed along options
74534        center || this._calcBounds();
74535        this._updateObjectsCoords(center);
74536        delete options.centerPoint;
74537        this.callSuper('initialize', options);
74538      }
74539      else {
74540        this._updateObjectsACoords();
74541      }
74542
74543      this.setCoords();
74544    },
74545
74546    /**
74547     * @private
74548     */
74549    _updateObjectsACoords: function() {
74550      var skipControls = true;
74551      for (var i = this._objects.length; i--; ){
74552        this._objects[i].setCoords(skipControls);
74553      }
74554    },
74555
74556    /**
74557     * @private
74558     * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change
74559     */
74560    _updateObjectsCoords: function(center) {
74561      var center = center || this.getCenterPoint();
74562      for (var i = this._objects.length; i--; ){
74563        this._updateObjectCoords(this._objects[i], center);
74564      }
74565    },
74566
74567    /**
74568     * @private
74569     * @param {Object} object
74570     * @param {fabric.Point} center, current center of group.
74571     */
74572    _updateObjectCoords: function(object, center) {
74573      var objectLeft = object.left,
74574          objectTop = object.top,
74575          skipControls = true;
74576
74577      object.set({
74578        left: objectLeft - center.x,
74579        top: objectTop - center.y
74580      });
74581      object.group = this;
74582      object.setCoords(skipControls);
74583    },
74584
74585    /**
74586     * Returns string represenation of a group
74587     * @return {String}
74588     */
74589    toString: function() {
74590      return '#<fabric.Group: (' + this.complexity() + ')>';
74591    },
74592
74593    /**
74594     * Adds an object to a group; Then recalculates group's dimension, position.
74595     * @param {Object} object
74596     * @return {fabric.Group} thisArg
74597     * @chainable
74598     */
74599    addWithUpdate: function(object) {
74600      var nested = !!this.group;
74601      this._restoreObjectsState();
74602      fabric.util.resetObjectTransform(this);
74603      if (object) {
74604        if (nested) {
74605          // if this group is inside another group, we need to pre transform the object
74606          fabric.util.removeTransformFromObject(object, this.group.calcTransformMatrix());
74607        }
74608        this._objects.push(object);
74609        object.group = this;
74610        object._set('canvas', this.canvas);
74611      }
74612      this._calcBounds();
74613      this._updateObjectsCoords();
74614      this.dirty = true;
74615      if (nested) {
74616        this.group.addWithUpdate();
74617      }
74618      else {
74619        this.setCoords();
74620      }
74621      return this;
74622    },
74623
74624    /**
74625     * Removes an object from a group; Then recalculates group's dimension, position.
74626     * @param {Object} object
74627     * @return {fabric.Group} thisArg
74628     * @chainable
74629     */
74630    removeWithUpdate: function(object) {
74631      this._restoreObjectsState();
74632      fabric.util.resetObjectTransform(this);
74633
74634      this.remove(object);
74635      this._calcBounds();
74636      this._updateObjectsCoords();
74637      this.setCoords();
74638      this.dirty = true;
74639      return this;
74640    },
74641
74642    /**
74643     * @private
74644     */
74645    _onObjectAdded: function(object) {
74646      this.dirty = true;
74647      object.group = this;
74648      object._set('canvas', this.canvas);
74649    },
74650
74651    /**
74652     * @private
74653     */
74654    _onObjectRemoved: function(object) {
74655      this.dirty = true;
74656      delete object.group;
74657    },
74658
74659    /**
74660     * @private
74661     */
74662    _set: function(key, value) {
74663      var i = this._objects.length;
74664      if (this.useSetOnGroup) {
74665        while (i--) {
74666          this._objects[i].setOnGroup(key, value);
74667        }
74668      }
74669      if (key === 'canvas') {
74670        while (i--) {
74671          this._objects[i]._set(key, value);
74672        }
74673      }
74674      fabric.Object.prototype._set.call(this, key, value);
74675    },
74676
74677    /**
74678     * Returns object representation of an instance
74679     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
74680     * @return {Object} object representation of an instance
74681     */
74682    toObject: function(propertiesToInclude) {
74683      var _includeDefaultValues = this.includeDefaultValues;
74684      var objsToObject = this._objects
74685        .filter(function (obj) {
74686          return !obj.excludeFromExport;
74687        })
74688        .map(function (obj) {
74689          var originalDefaults = obj.includeDefaultValues;
74690          obj.includeDefaultValues = _includeDefaultValues;
74691          var _obj = obj.toObject(propertiesToInclude);
74692          obj.includeDefaultValues = originalDefaults;
74693          return _obj;
74694        });
74695      var obj = fabric.Object.prototype.toObject.call(this, propertiesToInclude);
74696      obj.objects = objsToObject;
74697      return obj;
74698    },
74699
74700    /**
74701     * Returns object representation of an instance, in dataless mode.
74702     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
74703     * @return {Object} object representation of an instance
74704     */
74705    toDatalessObject: function(propertiesToInclude) {
74706      var objsToObject, sourcePath = this.sourcePath;
74707      if (sourcePath) {
74708        objsToObject = sourcePath;
74709      }
74710      else {
74711        var _includeDefaultValues = this.includeDefaultValues;
74712        objsToObject = this._objects.map(function(obj) {
74713          var originalDefaults = obj.includeDefaultValues;
74714          obj.includeDefaultValues = _includeDefaultValues;
74715          var _obj = obj.toDatalessObject(propertiesToInclude);
74716          obj.includeDefaultValues = originalDefaults;
74717          return _obj;
74718        });
74719      }
74720      var obj = fabric.Object.prototype.toDatalessObject.call(this, propertiesToInclude);
74721      obj.objects = objsToObject;
74722      return obj;
74723    },
74724
74725    /**
74726     * Renders instance on a given context
74727     * @param {CanvasRenderingContext2D} ctx context to render instance on
74728     */
74729    render: function(ctx) {
74730      this._transformDone = true;
74731      this.callSuper('render', ctx);
74732      this._transformDone = false;
74733    },
74734
74735    /**
74736     * Decide if the object should cache or not. Create its own cache level
74737     * needsItsOwnCache should be used when the object drawing method requires
74738     * a cache step. None of the fabric classes requires it.
74739     * Generally you do not cache objects in groups because the group is already cached.
74740     * @return {Boolean}
74741     */
74742    shouldCache: function() {
74743      var ownCache = fabric.Object.prototype.shouldCache.call(this);
74744      if (ownCache) {
74745        for (var i = 0, len = this._objects.length; i < len; i++) {
74746          if (this._objects[i].willDrawShadow()) {
74747            this.ownCaching = false;
74748            return false;
74749          }
74750        }
74751      }
74752      return ownCache;
74753    },
74754
74755    /**
74756     * Check if this object or a child object will cast a shadow
74757     * @return {Boolean}
74758     */
74759    willDrawShadow: function() {
74760      if (fabric.Object.prototype.willDrawShadow.call(this)) {
74761        return true;
74762      }
74763      for (var i = 0, len = this._objects.length; i < len; i++) {
74764        if (this._objects[i].willDrawShadow()) {
74765          return true;
74766        }
74767      }
74768      return false;
74769    },
74770
74771    /**
74772     * Check if this group or its parent group are caching, recursively up
74773     * @return {Boolean}
74774     */
74775    isOnACache: function() {
74776      return this.ownCaching || (this.group && this.group.isOnACache());
74777    },
74778
74779    /**
74780     * Execute the drawing operation for an object on a specified context
74781     * @param {CanvasRenderingContext2D} ctx Context to render on
74782     */
74783    drawObject: function(ctx) {
74784      for (var i = 0, len = this._objects.length; i < len; i++) {
74785        this._objects[i].render(ctx);
74786      }
74787      this._drawClipPath(ctx);
74788    },
74789
74790    /**
74791     * Check if cache is dirty
74792     */
74793    isCacheDirty: function(skipCanvas) {
74794      if (this.callSuper('isCacheDirty', skipCanvas)) {
74795        return true;
74796      }
74797      if (!this.statefullCache) {
74798        return false;
74799      }
74800      for (var i = 0, len = this._objects.length; i < len; i++) {
74801        if (this._objects[i].isCacheDirty(true)) {
74802          if (this._cacheCanvas) {
74803            // if this group has not a cache canvas there is nothing to clean
74804            var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY;
74805            this._cacheContext.clearRect(-x / 2, -y / 2, x, y);
74806          }
74807          return true;
74808        }
74809      }
74810      return false;
74811    },
74812
74813    /**
74814     * Restores original state of each of group objects (original state is that which was before group was created).
74815     * if the nested boolean is true, the original state will be restored just for the
74816     * first group and not for all the group chain
74817     * @private
74818     * @param {Boolean} nested tell the function to restore object state up to the parent group and not more
74819     * @return {fabric.Group} thisArg
74820     * @chainable
74821     */
74822    _restoreObjectsState: function() {
74823      var groupMatrix = this.calcOwnMatrix();
74824      this._objects.forEach(function(object) {
74825        // instead of using _this = this;
74826        fabric.util.addTransformToObject(object, groupMatrix);
74827        delete object.group;
74828        object.setCoords();
74829      });
74830      return this;
74831    },
74832
74833    /**
74834     * Realises the transform from this group onto the supplied object
74835     * i.e. it tells you what would happen if the supplied object was in
74836     * the group, and then the group was destroyed. It mutates the supplied
74837     * object.
74838     * Warning: this method is not useful anymore, it has been kept to no break the api.
74839     * is not used in the fabricJS codebase
74840     * this method will be reduced to using the utility.
74841     * @private
74842     * @deprecated
74843     * @param {fabric.Object} object
74844     * @param {Array} parentMatrix parent transformation
74845     * @return {fabric.Object} transformedObject
74846     */
74847    realizeTransform: function(object, parentMatrix) {
74848      fabric.util.addTransformToObject(object, parentMatrix);
74849      return object;
74850    },
74851
74852    /**
74853     * Destroys a group (restoring state of its objects)
74854     * @return {fabric.Group} thisArg
74855     * @chainable
74856     */
74857    destroy: function() {
74858      // when group is destroyed objects needs to get a repaint to be eventually
74859      // displayed on canvas.
74860      this._objects.forEach(function(object) {
74861        object.set('dirty', true);
74862      });
74863      return this._restoreObjectsState();
74864    },
74865
74866    /**
74867     * make a group an active selection, remove the group from canvas
74868     * the group has to be on canvas for this to work.
74869     * @return {fabric.ActiveSelection} thisArg
74870     * @chainable
74871     */
74872    toActiveSelection: function() {
74873      if (!this.canvas) {
74874        return;
74875      }
74876      var objects = this._objects, canvas = this.canvas;
74877      this._objects = [];
74878      var options = this.toObject();
74879      delete options.objects;
74880      var activeSelection = new fabric.ActiveSelection([]);
74881      activeSelection.set(options);
74882      activeSelection.type = 'activeSelection';
74883      canvas.remove(this);
74884      objects.forEach(function(object) {
74885        object.group = activeSelection;
74886        object.dirty = true;
74887        canvas.add(object);
74888      });
74889      activeSelection.canvas = canvas;
74890      activeSelection._objects = objects;
74891      canvas._activeObject = activeSelection;
74892      activeSelection.setCoords();
74893      return activeSelection;
74894    },
74895
74896    /**
74897     * Destroys a group (restoring state of its objects)
74898     * @return {fabric.Group} thisArg
74899     * @chainable
74900     */
74901    ungroupOnCanvas: function() {
74902      return this._restoreObjectsState();
74903    },
74904
74905    /**
74906     * Sets coordinates of all objects inside group
74907     * @return {fabric.Group} thisArg
74908     * @chainable
74909     */
74910    setObjectsCoords: function() {
74911      var skipControls = true;
74912      this.forEachObject(function(object) {
74913        object.setCoords(skipControls);
74914      });
74915      return this;
74916    },
74917
74918    /**
74919     * @private
74920     */
74921    _calcBounds: function(onlyWidthHeight) {
74922      var aX = [],
74923          aY = [],
74924          o, prop, coords,
74925          props = ['tr', 'br', 'bl', 'tl'],
74926          i = 0, iLen = this._objects.length,
74927          j, jLen = props.length;
74928
74929      for ( ; i < iLen; ++i) {
74930        o = this._objects[i];
74931        coords = o.calcACoords();
74932        for (j = 0; j < jLen; j++) {
74933          prop = props[j];
74934          aX.push(coords[prop].x);
74935          aY.push(coords[prop].y);
74936        }
74937        o.aCoords = coords;
74938      }
74939
74940      this._getBounds(aX, aY, onlyWidthHeight);
74941    },
74942
74943    /**
74944     * @private
74945     */
74946    _getBounds: function(aX, aY, onlyWidthHeight) {
74947      var minXY = new fabric.Point(min(aX), min(aY)),
74948          maxXY = new fabric.Point(max(aX), max(aY)),
74949          top = minXY.y || 0, left = minXY.x || 0,
74950          width = (maxXY.x - minXY.x) || 0,
74951          height = (maxXY.y - minXY.y) || 0;
74952      this.width = width;
74953      this.height = height;
74954      if (!onlyWidthHeight) {
74955        // the bounding box always finds the topleft most corner.
74956        // whatever is the group origin, we set up here the left/top position.
74957        this.setPositionByOrigin({ x: left, y: top }, 'left', 'top');
74958      }
74959    },
74960
74961    /* _TO_SVG_START_ */
74962    /**
74963     * Returns svg representation of an instance
74964     * @param {Function} [reviver] Method for further parsing of svg representation.
74965     * @return {String} svg representation of an instance
74966     */
74967    _toSVG: function(reviver) {
74968      var svgString = ['<g ', 'COMMON_PARTS', ' >\n'];
74969
74970      for (var i = 0, len = this._objects.length; i < len; i++) {
74971        svgString.push('\t\t', this._objects[i].toSVG(reviver));
74972      }
74973      svgString.push('</g>\n');
74974      return svgString;
74975    },
74976
74977    /**
74978     * Returns styles-string for svg-export, specific version for group
74979     * @return {String}
74980     */
74981    getSvgStyles: function() {
74982      var opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ?
74983            'opacity: ' + this.opacity + ';' : '',
74984          visibility = this.visible ? '' : ' visibility: hidden;';
74985      return [
74986        opacity,
74987        this.getSvgFilter(),
74988        visibility
74989      ].join('');
74990    },
74991
74992    /**
74993     * Returns svg clipPath representation of an instance
74994     * @param {Function} [reviver] Method for further parsing of svg representation.
74995     * @return {String} svg representation of an instance
74996     */
74997    toClipPathSVG: function(reviver) {
74998      var svgString = [];
74999
75000      for (var i = 0, len = this._objects.length; i < len; i++) {
75001        svgString.push('\t', this._objects[i].toClipPathSVG(reviver));
75002      }
75003
75004      return this._createBaseClipPathSVGMarkup(svgString, { reviver: reviver });
75005    },
75006    /* _TO_SVG_END_ */
75007  });
75008
75009  /**
75010   * Returns {@link fabric.Group} instance from an object representation
75011   * @static
75012   * @memberOf fabric.Group
75013   * @param {Object} object Object to create a group from
75014   * @param {Function} [callback] Callback to invoke when an group instance is created
75015   */
75016  fabric.Group.fromObject = function(object, callback) {
75017    var objects = object.objects,
75018        options = fabric.util.object.clone(object, true);
75019    delete options.objects;
75020    if (typeof objects === 'string') {
75021      // it has to be an url or something went wrong.
75022      fabric.loadSVGFromURL(objects, function (elements) {
75023        var group = fabric.util.groupSVGElements(elements, object, objects);
75024        group.set(options);
75025        callback && callback(group);
75026      });
75027      return;
75028    }
75029    fabric.util.enlivenObjects(objects, function(enlivenedObjects) {
75030      fabric.util.enlivenObjects([object.clipPath], function(enlivedClipPath) {
75031        var options = fabric.util.object.clone(object, true);
75032        options.clipPath = enlivedClipPath[0];
75033        delete options.objects;
75034        callback && callback(new fabric.Group(enlivenedObjects, options, true));
75035      });
75036    });
75037  };
75038
75039})( true ? exports : 
75039this);
75040
75041
75042(function(global) {
75043
75044  'use strict';
75045
75046  var fabric = global.fabric || (global.fabric = { });
75047
75048  if (fabric.ActiveSelection) {
75049    return;
75050  }
75051
75052  /**
75053   * Group class
75054   * @class fabric.ActiveSelection
75055   * @extends fabric.Group
75056   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}
75057   * @see {@link fabric.ActiveSelection#initialize} for constructor definition
75058   */
75059  fabric.ActiveSelection = fabric.util.createClass(fabric.Group, /** @lends fabric.ActiveSelection.prototype */ {
75060
75061    /**
75062     * Type of an object
vendor: 4,168 bytes, lines 75063-75196
75063     * @type String
75064     * @default
75065     */
75066    type: 'activeSelection',
75067
75068    /**
75069     * Constructor
75070     * @param {Object} objects ActiveSelection objects
75071     * @param {Object} [options] Options object
75072     * @return {Object} thisArg
75073     */
75074    initialize: function(objects, options) {
75075      options = options || {};
75076      this._objects = objects || [];
75077      for (var i = this._objects.length; i--; ) {
75078        this._objects[i].group = this;
75079      }
75080
75081      if (options.originX) {
75082        this.originX = options.originX;
75083      }
75084      if (options.originY) {
75085        this.originY = options.originY;
75086      }
75087      this._calcBounds();
75088      this._updateObjectsCoords();
75089      fabric.Object.prototype.initialize.call(this, options);
75090      this.setCoords();
75091    },
75092
75093    /**
75094     * Change te activeSelection to a normal group,
75095     * High level function that automatically adds it to canvas as
75096     * active object. no events fired.
75097     * @since 2.0.0
75098     * @return {fabric.Group}
75099     */
75100    toGroup: function() {
75101      var objects = this._objects.concat();
75102      this._objects = [];
75103      var options = fabric.Object.prototype.toObject.call(this);
75104      var newGroup = new fabric.Group([]);
75105      delete options.type;
75106      newGroup.set(options);
75107      objects.forEach(function(object) {
75108        object.canvas.remove(object);
75109        object.group = newGroup;
75110      });
75111      newGroup._objects = objects;
75112      if (!this.canvas) {
75113        return newGroup;
75114      }
75115      var canvas = this.canvas;
75116      canvas.add(newGroup);
75117      canvas._activeObject = newGroup;
75118      newGroup.setCoords();
75119      return newGroup;
75120    },
75121
75122    /**
75123     * If returns true, deselection is cancelled.
75124     * @since 2.0.0
75125     * @return {Boolean} [cancel]
75126     */
75127    onDeselect: function() {
75128      this.destroy();
75129      return false;
75130    },
75131
75132    /**
75133     * Returns string representation of a group
75134     * @return {String}
75135     */
75136    toString: function() {
75137      return '#<fabric.ActiveSelection: (' + this.complexity() + ')>';
75138    },
75139
75140    /**
75141     * Decide if the object should cache or not. Create its own cache level
75142     * objectCaching is a global flag, wins over everything
75143     * needsItsOwnCache should be used when the object drawing method requires
75144     * a cache step. None of the fabric classes requires it.
75145     * Generally you do not cache objects in groups because the group outside is cached.
75146     * @return {Boolean}
75147     */
75148    shouldCache: function() {
75149      return false;
75150    },
75151
75152    /**
75153     * Check if this group or its parent group are caching, recursively up
75154     * @return {Boolean}
75155     */
75156    isOnACache: function() {
75157      return false;
75158    },
75159
75160    /**
75161     * Renders controls and borders for the object
75162     * @param {CanvasRenderingContext2D} ctx Context to render on
75163     * @param {Object} [styleOverride] properties to override the object style
75164     * @param {Object} [childrenOverride] properties to override the children overrides
75165     */
75166    _renderControls: function(ctx, styleOverride, childrenOverride) {
75167      ctx.save();
75168      ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;
75169      this.callSuper('_renderControls', ctx, styleOverride);
75170      childrenOverride = childrenOverride || { };
75171      if (typeof childrenOverride.hasControls === 'undefined') {
75172        childrenOverride.hasControls = false;
75173      }
75174      childrenOverride.forActiveSelection = true;
75175      for (var i = 0, len = this._objects.length; i < len; i++) {
75176        this._objects[i]._renderControls(ctx, childrenOverride);
75177      }
75178      ctx.restore();
75179    },
75180  });
75181
75182  /**
75183   * Returns {@link fabric.ActiveSelection} instance from an object representation
75184   * @static
75185   * @memberOf fabric.ActiveSelection
75186   * @param {Object} object Object to create a group from
75187   * @param {Function} [callback] Callback to invoke when an ActiveSelection instance is created
75188   */
75189  fabric.ActiveSelection.fromObject = function(object, callback) {
75190    fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) {
75191      delete object.objects;
75192      callback && callback(new fabric.ActiveSelection(enlivenedObjects, object, true));
75193    });
75194  };
75195
75196})( true ? exports : this
vendor: 25,967 bytes, lines 75196-75962
75196);
75197
75198
75199(function(global) {
75200
75201  'use strict';
75202
75203  var extend = fabric.util.object.extend;
75204
75205  if (!global.fabric) {
75206    global.fabric = { };
75207  }
75208
75209  if (global.fabric.Image) {
75210    fabric.warn('fabric.Image is already defined.');
75211    return;
75212  }
75213
75214  /**
75215   * Image class
75216   * @class fabric.Image
75217   * @extends fabric.Object
75218   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images}
75219   * @see {@link fabric.Image#initialize} for constructor definition
75220   */
75221  fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ {
75222
75223    /**
75224     * Type of an object
75225     * @type String
75226     * @default
75227     */
75228    type: 'image',
75229
75230    /**
75231     * Width of a stroke.
75232     * For image quality a stroke multiple of 2 gives better results.
75233     * @type Number
75234     * @default
75235     */
75236    strokeWidth: 0,
75237
75238    /**
75239     * When calling {@link fabric.Image.getSrc}, return value from element src with `element.getAttribute('src')`.
75240     * This allows for relative urls as image src.
75241     * @since 2.7.0
75242     * @type Boolean
75243     * @default
75244     */
75245    srcFromAttribute: false,
75246
75247    /**
75248     * private
75249     * contains last value of scaleX to detect
75250     * if the Image got resized after the last Render
75251     * @type Number
75252     */
75253    _lastScaleX: 1,
75254
75255    /**
75256     * private
75257     * contains last value of scaleY to detect
75258     * if the Image got resized after the last Render
75259     * @type Number
75260     */
75261    _lastScaleY: 1,
75262
75263    /**
75264     * private
75265     * contains last value of scaling applied by the apply filter chain
75266     * @type Number
75267     */
75268    _filterScalingX: 1,
75269
75270    /**
75271     * private
75272     * contains last value of scaling applied by the apply filter chain
75273     * @type Number
75274     */
75275    _filterScalingY: 1,
75276
75277    /**
75278     * minimum scale factor under which any resizeFilter is triggered to resize the image
75279     * 0 will disable the automatic resize. 1 will trigger automatically always.
75280     * number bigger than 1 are not implemented yet.
75281     * @type Number
75282     */
75283    minimumScaleTrigger: 0.5,
75284
75285    /**
75286     * List of properties to consider when checking if
75287     * state of an object is changed ({@link fabric.Object#hasStateChanged})
75288     * as well as for history (undo/redo) purposes
75289     * @type Array
75290     */
75291    stateProperties: fabric.Object.prototype.stateProperties.concat('cropX', 'cropY'),
75292
75293    /**
75294     * List of properties to consider when checking if cache needs refresh
75295     * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single
75296     * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty
75297     * and refreshed at the next render
75298     * @type Array
75299     */
75300    cacheProperties: fabric.Object.prototype.cacheProperties.concat('cropX', 'cropY'),
75301
75302    /**
75303     * key used to retrieve the texture representing this image
75304     * @since 2.0.0
75305     * @type String
75306     * @default
75307     */
75308    cacheKey: '',
75309
75310    /**
75311     * Image crop in pixels from original image size.
75312     * @since 2.0.0
75313     * @type Number
75314     * @default
75315     */
75316    cropX: 0,
75317
75318    /**
75319     * Image crop in pixels from original image size.
75320     * @since 2.0.0
75321     * @type Number
75322     * @default
75323     */
75324    cropY: 0,
75325
75326    /**
75327     * Indicates whether this canvas will use image smoothing when painting this image.
75328     * Also influence if the cacheCanvas for this image uses imageSmoothing
75329     * @since 4.0.0-beta.11
75330     * @type Boolean
75331     * @default
75332     */
75333    imageSmoothing: true,
75334
75335    /**
75336     * Constructor
75337     * Image can be initialized with any canvas drawable or a string.
75338     * The string should be a url and will be loaded as an image.
75339     * Canvas and Image element work out of the box, while videos require extra code to work.
75340     * Please check video element events for seeking.
75341     * @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | String} element Image element
75342     * @param {Object} [options] Options object
75343     * @param {function} [callback] callback function to call after eventual filters applied.
75344     * @return {fabric.Image} thisArg
75345     */
75346    initialize: function(element, options) {
75347      options || (options = { });
75348      this.filters = [];
75349      this.cacheKey = 'texture' + fabric.Object.__uid++;
75350      this.callSuper('initialize', options);
75351      this._initElement(element, options);
75352    },
75353
75354    /**
75355     * Returns image element which this instance if based on
75356     * @return {HTMLImageElement} Image element
75357     */
75358    getElement: function() {
75359      return this._element || {};
75360    },
75361
75362    /**
75363     * Sets image element for this instance to a specified one.
75364     * If filters defined they are applied to new image.
75365     * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area.
75366     * @param {HTMLImageElement} element
75367     * @param {Object} [options] Options object
75368     * @return {fabric.Image} thisArg
75369     * @chainable
75370     */
75371    setElement: function(element, options) {
75372      this.removeTexture(this.cacheKey);
75373      this.removeTexture(this.cacheKey + '_filtered');
75374      this._element = element;
75375      this._originalElement = element;
75376      this._initConfig(options);
75377      if (this.filters.length !== 0) {
75378        this.applyFilters();
75379      }
75380      // resizeFilters work on the already filtered copy.
75381      // we need to apply resizeFilters AFTER normal filters.
75382      // applyResizeFilters is run more often than normal filters
75383      // and is triggered by user interactions rather than dev code
75384      if (this.resizeFilter) {
75385        this.applyResizeFilters();
75386      }
75387      return this;
75388    },
75389
75390    /**
75391     * Delete a single texture if in webgl mode
75392     */
75393    removeTexture: function(key) {
75394      var backend = fabric.filterBackend;
75395      if (backend && backend.evictCachesForKey) {
75396        backend.evictCachesForKey(key);
75397      }
75398    },
75399
75400    /**
75401     * Delete textures, reference to elements and eventually JSDOM cleanup
75402     */
75403    dispose: function() {
75404      this.removeTexture(this.cacheKey);
75405      this.removeTexture(this.cacheKey + '_filtered');
75406      this._cacheContext = undefined;
75407      ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach((function(element) {
75408        fabric.util.cleanUpJsdomNode(this[element]);
75409        this[element] = undefined;
75410      }).bind(this));
75411    },
75412
75413    /**
75414     * Get the crossOrigin value (of the corresponding image element)
75415     */
75416    getCrossOrigin: function() {
75417      return this._originalElement && (this._originalElement.crossOrigin || null);
75418    },
75419
75420    /**
75421     * Returns original size of an image
75422     * @return {Object} Object with "width" and "height" properties
75423     */
75424    getOriginalSize: function() {
75425      var element = this.getElement();
75426      return {
75427        width: element.naturalWidth || element.width,
75428        height: element.naturalHeight || element.height
75429      };
75430    },
75431
75432    /**
75433     * @private
75434     * @param {CanvasRenderingContext2D} ctx Context to render on
75435     */
75436    _stroke: function(ctx) {
75437      if (!this.stroke || this.strokeWidth === 0) {
75438        return;
75439      }
75440      var w = this.width / 2, h = this.height / 2;
75441      ctx.beginPath();
75442      ctx.moveTo(-w, -h);
75443      ctx.lineTo(w, -h);
75444      ctx.lineTo(w, h);
75445      ctx.lineTo(-w, h);
75446      ctx.lineTo(-w, -h);
75447      ctx.closePath();
75448    },
75449
75450    /**
75451     * Returns object representation of an instance
75452     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
75453     * @return {Object} Object representation of an instance
75454     */
75455    toObject: function(propertiesToInclude) {
75456      var filters = [];
75457
75458      this.filters.forEach(function(filterObj) {
75459        if (filterObj) {
75460          filters.push(filterObj.toObject());
75461        }
75462      });
75463      var object = extend(
75464        this.callSuper(
75465          'toObject',
75466          ['cropX', 'cropY'].concat(propertiesToInclude)
75467        ), {
75468          src: this.getSrc(),
75469          crossOrigin: this.getCrossOrigin(),
75470          filters: filters,
75471        });
75472      if (this.resizeFilter) {
75473        object.resizeFilter = this.resizeFilter.toObject();
75474      }
75475      return object;
75476    },
75477
75478    /**
75479     * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,height.
75480     * @return {Boolean}
75481     */
75482    hasCrop: function() {
75483      return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height;
75484    },
75485
75486    /* _TO_SVG_START_ */
75487    /**
75488     * Returns svg representation of an instance
75489     * @return {Array} an array of strings with the specific svg representation
75490     * of the instance
75491     */
75492    _toSVG: function() {
75493      var svgString = [], imageMarkup = [], strokeSvg, element = this._element,
75494          x = -this.width / 2, y = -this.height / 2, clipPath = '', imageRendering = '';
75495      if (!element) {
75496        return [];
75497      }
75498      if (this.hasCrop()) {
75499        var clipPathId = fabric.Object.__uid++;
75500        svgString.push(
75501          '<clipPath id="imageCrop_' + clipPathId + '">\n',
75502          '\t<rect x="' + x + '" y="' + y + '" width="' + this.width + '" height="' + this.height + '" />\n',
75503          '</clipPath>\n'
75504        );
75505        clipPath = ' clip-path="url(#imageCrop_' + clipPathId + ')" ';
75506      }
75507      if (!this.imageSmoothing) {
75508        imageRendering = '" image-rendering="optimizeSpeed';
75509      }
75510      imageMarkup.push('\t<image ', 'COMMON_PARTS', 'xlink:href="', this.getSvgSrc(true),
75511        '" x="', x - this.cropX, '" y="', y - this.cropY,
75512        // we're essentially moving origin of transformation from top/left corner to the center of the shape
75513        // by wrapping it in container <g> element with actual transformation, then offsetting object to the top/left
75514        // so that object's center aligns with container's left/top
75515        '" width="', element.width || element.naturalWidth,
75516        '" height="', element.height || element.height,
75517        imageRendering,
75518        '"', clipPath,
75519        '></image>\n');
75520
75521      if (this.stroke || this.strokeDashArray) {
75522        var origFill = this.fill;
75523        this.fill = null;
75524        strokeSvg = [
75525          '\t<rect ',
75526          'x="', x, '" y="', y,
75527          '" width="', this.width, '" height="', this.height,
75528          '" style="', this.getSvgStyles(),
75529          '"/>\n'
75530        ];
75531        this.fill = origFill;
75532      }
75533      if (this.paintFirst !== 'fill') {
75534        svgString = svgString.concat(strokeSvg, imageMarkup);
75535      }
75536      else {
75537        svgString = svgString.concat(imageMarkup, strokeSvg);
75538      }
75539      return svgString;
75540    },
75541    /* _TO_SVG_END_ */
75542
75543    /**
75544     * Returns source of an image
75545     * @param {Boolean} filtered indicates if the src is needed for svg
75546     * @return {String} Source of an image
75547     */
75548    getSrc: function(filtered) {
75549      var element = filtered ? this._element : this._originalElement;
75550      if (element) {
75551        if (element.toDataURL) {
75552          return element.toDataURL();
75553        }
75554
75555        if (this.srcFromAttribute) {
75556          return element.getAttribute('src');
75557        }
75558        else {
75559          return element.src;
75560        }
75561      }
75562      else {
75563        return this.src || '';
75564      }
75565    },
75566
75567    /**
75568     * Sets source of an image
75569     * @param {String} src Source string (URL)
75570     * @param {Function} [callback] Callback is invoked when image has been loaded (and all filters have been applied)
75571     * @param {Object} [options] Options object
75572     * @param {String} [options.crossOrigin] crossOrigin value (one of "", "anonymous", "use-credentials")
75573     * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes
75574     * @return {fabric.Image} thisArg
75575     * @chainable
75576     */
75577    setSrc: function(src, callback, options) {
75578      fabric.util.loadImage(src, function(img, isError) {
75579        this.setElement(img, options);
75580        this._setWidthHeight();
75581        callback && callback(this, isError);
75582      }, this, options && options.crossOrigin);
75583      return this;
75584    },
75585
75586    /**
75587     * Returns string representation of an instance
75588     * @return {String} String representation of an instance
75589     */
75590    toString: function() {
75591      return '#<fabric.Image: { src: "' + this.getSrc() + '" }>';
75592    },
75593
75594    applyResizeFilters: function() {
75595      var filter = this.resizeFilter,
75596          minimumScale = this.minimumScaleTrigger,
75597          objectScale = this.getTotalObjectScaling(),
75598          scaleX = objectScale.scaleX,
75599          scaleY = objectScale.scaleY,
75600          elementToFilter = this._filteredEl || this._originalElement;
75601      if (this.group) {
75602        this.set('dirty', true);
75603      }
75604      if (!filter || (scaleX > minimumScale && scaleY > minimumScale)) {
75605        this._element = elementToFilter;
75606        this._filterScalingX = 1;
75607        this._filterScalingY = 1;
75608        this._lastScaleX = scaleX;
75609        this._lastScaleY = scaleY;
75610        return;
75611      }
75612      if (!fabric.filterBackend) {
75613        fabric.filterBackend = fabric.initFilterBackend();
75614      }
75615      var canvasEl = fabric.util.createCanvasElement(),
75616          cacheKey = this._filteredEl ? (this.cacheKey + '_filtered') : this.cacheKey,
75617          sourceWidth = elementToFilter.width, sourceHeight = elementToFilter.height;
75618      canvasEl.width = sourceWidth;
75619      canvasEl.height = sourceHeight;
75620      this._element = canvasEl;
75621      this._lastScaleX = filter.scaleX = scaleX;
75622      this._lastScaleY = filter.scaleY = scaleY;
75623      fabric.filterBackend.applyFilters(
75624        [filter], elementToFilter, sourceWidth, sourceHeight, this._element, cacheKey);
75625      this._filterScalingX = canvasEl.width / this._originalElement.width;
75626      this._filterScalingY = canvasEl.height / this._originalElement.height;
75627    },
75628
75629    /**
75630     * Applies filters assigned to this image (from "filters" array) or from filter param
75631     * @method applyFilters
75632     * @param {Array} filters to be applied
75633     * @param {Boolean} forResizing specify if the filter operation is a resize operation
75634     * @return {thisArg} return the fabric.Image object
75635     * @chainable
75636     */
75637    applyFilters: function(filters) {
75638
75639      filters = filters || this.filters || [];
75640      filters = filters.filter(function(filter) { return filter && !filter.isNeutralState(); });
75641      this.set('dirty', true);
75642
75643      // needs to clear out or WEBGL will not resize correctly
75644      this.removeTexture(this.cacheKey + '_filtered');
75645
75646      if (filters.length === 0) {
75647        this._element = this._originalElement;
75648        this._filteredEl = null;
75649        this._filterScalingX = 1;
75650        this._filterScalingY = 1;
75651        return this;
75652      }
75653
75654      var imgElement = this._originalElement,
75655          sourceWidth = imgElement.naturalWidth || imgElement.width,
75656          sourceHeight = imgElement.naturalHeight || imgElement.height;
75657
75658      if (this._element === this._originalElement) {
75659        // if the element is the same we need to create a new element
75660        var canvasEl = fabric.util.createCanvasElement();
75661        canvasEl.width = sourceWidth;
75662        canvasEl.height = sourceHeight;
75663        this._element = canvasEl;
75664        this._filteredEl = canvasEl;
75665      }
75666      else {
75667        // clear the existing element to get new filter data
75668        // also dereference the eventual resized _element
75669        this._element = this._filteredEl;
75670        this._filteredEl.getContext('2d').clearRect(0, 0, sourceWidth, sourceHeight);
75671        // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y
75672        this._lastScaleX = 1;
75673        this._lastScaleY = 1;
75674      }
75675      if (!fabric.filterBackend) {
75676        fabric.filterBackend = fabric.initFilterBackend();
75677      }
75678      fabric.filterBackend.applyFilters(
75679        filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey);
75680      if (this._originalElement.width !== this._element.width ||
75681        this._originalElement.height !== this._element.height) {
75682        this._filterScalingX = this._element.width / this._originalElement.width;
75683        this._filterScalingY = this._element.height / this._originalElement.height;
75684      }
75685      return this;
75686    },
75687
75688    /**
75689     * @private
75690     * @param {CanvasRenderingContext2D} ctx Context to render on
75691     */
75692    _render: function(ctx) {
75693      fabric.util.setImageSmoothing(ctx, this.imageSmoothing);
75694      if (this.isMoving !== true && this.resizeFilter && this._needsResize()) {
75695        this.applyResizeFilters();
75696      }
75697      this._stroke(ctx);
75698      this._renderPaintInOrder(ctx);
75699    },
75700
75701    /**
75702     * Paint the cached copy of the object on the target context.
75703     * it will set the imageSmoothing for the draw operation
75704     * @param {CanvasRenderingContext2D} ctx Context to render on
75705     */
75706    drawCacheOnCanvas: function(ctx) {
75707      fabric.util.setImageSmoothing(ctx, this.imageSmoothing);
75708      fabric.Object.prototype.drawCacheOnCanvas.call(this, ctx);
75709    },
75710
75711    /**
75712     * Decide if the object should cache or not. Create its own cache level
75713     * needsItsOwnCache should be used when the object drawing method requires
75714     * a cache step. None of the fabric classes requires it.
75715     * Generally you do not cache objects in groups because the group outside is cached.
75716     * This is the special image version where we would like to avoid caching where possible.
75717     * Essentially images do not benefit from caching. They may require caching, and in that
75718     * case we do it. Also caching an image usually ends in a loss of details.
75719     * A full performance audit should be done.
75720     * @return {Boolean}
75721     */
75722    shouldCache: function() {
75723      return this.needsItsOwnCache();
75724    },
75725
75726    _renderFill: function(ctx) {
75727      var elementToDraw = this._element;
75728      if (!elementToDraw) {
75729        return;
75730      }
75731      var scaleX = this._filterScalingX, scaleY = this._filterScalingY,
75732          w = this.width, h = this.height, min = Math.min, max = Math.max,
75733          // crop values cannot be lesser than 0.
75734          cropX = max(this.cropX, 0), cropY = max(this.cropY, 0),
75735          elWidth = elementToDraw.naturalWidth || elementToDraw.width,
75736          elHeight = elementToDraw.naturalHeight || elementToDraw.height,
75737          sX = cropX * scaleX,
75738          sY = cropY * scaleY,
75739          // the width height cannot exceed element width/height, starting from the crop offset.
75740          sW = min(w * scaleX, elWidth - sX),
75741          sH = min(h * scaleY, elHeight - sY),
75742          x = -w / 2, y = -h / 2,
75743          maxDestW = min(w, elWidth / scaleX - cropX),
75744          maxDestH = min(h, elHeight / scaleY - cropY);
75745
75746      elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH);
75747    },
75748
75749    /**
75750     * needed to check if image needs resize
75751     * @private
75752     */
75753    _needsResize: function() {
75754      var scale = this.getTotalObjectScaling();
75755      return (scale.scaleX !== this._lastScaleX || scale.scaleY !== this._lastScaleY);
75756    },
75757
75758    /**
75759     * @private
75760     */
75761    _resetWidthHeight: function() {
75762      this.set(this.getOriginalSize());
75763    },
75764
75765    /**
75766     * The Image class's initialization method. This method is automatically
75767     * called by the constructor.
75768     * @private
75769     * @param {HTMLImageElement|String} element The element representing the image
75770     * @param {Object} [options] Options object
75771     */
75772    _initElement: function(element, options) {
75773      this.setElement(fabric.util.getById(element), options);
75774      fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS);
75775    },
75776
75777    /**
75778     * @private
75779     * @param {Object} [options] Options object
75780     */
75781    _initConfig: function(options) {
75782      options || (options = { });
75783      this.setOptions(options);
75784      this._setWidthHeight(options);
75785    },
75786
75787    /**
75788     * @private
75789     * @param {Array} filters to be initialized
75790     * @param {Function} callback Callback to invoke when all fabric.Image.filters instances are created
75791     */
75792    _initFilters: function(filters, callback) {
75793      if (filters && filters.length) {
75794        fabric.util.enlivenObjects(filters, function(enlivenedObjects) {
75795          callback && callback(enlivenedObjects);
75796        }, 'fabric.Image.filters');
75797      }
75798      else {
75799        callback && callback();
75800      }
75801    },
75802
75803    /**
75804     * @private
75805     * Set the width and the height of the image object, using the element or the
75806     * options.
75807     * @param {Object} [options] Object with width/height properties
75808     */
75809    _setWidthHeight: function(options) {
75810      options || (options = { });
75811      var el = this.getElement();
75812      this.width = options.width || el.naturalWidth || el.width || 0;
75813      this.height = options.height || el.naturalHeight || el.height || 0;
75814    },
75815
75816    /**
75817     * Calculate offset for center and scale factor for the image in order to respect
75818     * the preserveAspectRatio attribute
75819     * @private
75820     * @return {Object}
75821     */
75822    parsePreserveAspectRatioAttribute: function() {
75823      var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''),
75824          rWidth = this._element.width, rHeight = this._element.height,
75825          scaleX = 1, scaleY = 1, offsetLeft = 0, offsetTop = 0, cropX = 0, cropY = 0,
75826          offset, pWidth = this.width, pHeight = this.height, parsedAttributes = { width: pWidth, height: pHeight };
75827      if (pAR && (pAR.alignX !== 'none' || pAR.alignY !== 'none')) {
75828        if (pAR.meetOrSlice === 'meet') {
75829          scaleX = scaleY = fabric.util.findScaleToFit(this._element, parsedAttributes);
75830          offset = (pWidth - rWidth * scaleX) / 2;
75831          if (pAR.alignX === 'Min') {
75832            offsetLeft = -offset;
75833          }
75834          if (pAR.alignX === 'Max') {
75835            offsetLeft = offset;
75836          }
75837          offset = (pHeight - rHeight * scaleY) / 2;
75838          if (pAR.alignY === 'Min') {
75839            offsetTop = -offset;
75840          }
75841          if (pAR.alignY === 'Max') {
75842            offsetTop = offset;
75843          }
75844        }
75845        if (pAR.meetOrSlice === 'slice') {
75846          scaleX = scaleY = fabric.util.findScaleToCover(this._element, parsedAttributes);
75847          offset = rWidth - pWidth / scaleX;
75848          if (pAR.alignX === 'Mid') {
75849            cropX = offset / 2;
75850          }
75851          if (pAR.alignX === 'Max') {
75852            cropX = offset;
75853          }
75854          offset = rHeight - pHeight / scaleY;
75855          if (pAR.alignY === 'Mid') {
75856            cropY = offset / 2;
75857          }
75858          if (pAR.alignY === 'Max') {
75859            cropY = offset;
75860          }
75861          rWidth = pWidth / scaleX;
75862          rHeight = pHeight / scaleY;
75863        }
75864      }
75865      else {
75866        scaleX = pWidth / rWidth;
75867        scaleY = pHeight / rHeight;
75868      }
75869      return {
75870        width: rWidth,
75871        height: rHeight,
75872        scaleX: scaleX,
75873        scaleY: scaleY,
75874        offsetLeft: offsetLeft,
75875        offsetTop: offsetTop,
75876        cropX: cropX,
75877        cropY: cropY
75878      };
75879    }
75880  });
75881
75882  /**
75883   * Default CSS class name for canvas
75884   * @static
75885   * @type String
75886   * @default
75887   */
75888  fabric.Image.CSS_CANVAS = 'canvas-img';
75889
75890  /**
75891   * Alias for getSrc
75892   * @static
75893   */
75894  fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc;
75895
75896  /**
75897   * Creates an instance of fabric.Image from its object representation
75898   * @static
75899   * @param {Object} object Object to create an instance from
75900   * @param {Function} callback Callback to invoke when an image instance is created
75901   */
75902  fabric.Image.fromObject = function(_object, callback) {
75903    var object = fabric.util.object.clone(_object);
75904    fabric.util.loadImage(object.src, function(img, isError) {
75905      if (isError) {
75906        callback && callback(null, true);
75907        return;
75908      }
75909      fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) {
75910        object.filters = filters || [];
75911        fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function(resizeFilters) {
75912          object.resizeFilter = resizeFilters[0];
75913          fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {
75914            object.clipPath = enlivedProps[0];
75915            var image = new fabric.Image(img, object);
75916            callback(image, false);
75917          });
75918        });
75919      });
75920    }, null, object.crossOrigin);
75921  };
75922
75923  /**
75924   * Creates an instance of fabric.Image from an URL string
75925   * @static
75926   * @param {String} url URL to create an image from
75927   * @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument). Second argument is a boolean indicating if an error occurred or not.
75928   * @param {Object} [imgOptions] Options object
75929   */
75930  fabric.Image.fromURL = function(url, callback, imgOptions) {
75931    fabric.util.loadImage(url, function(img, isError) {
75932      callback && callback(new fabric.Image(img, imgOptions), isError);
75933    }, null, imgOptions && imgOptions.crossOrigin);
75934  };
75935
75936  /* _FROM_SVG_START_ */
75937  /**
75938   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement})
75939   * @static
75940   * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}
75941   */
75942  fabric.Image.ATTRIBUTE_NAMES =
75943    fabric.SHARED_ATTRIBUTES.concat(
75944      'x y width height preserveAspectRatio xlink:href crossOrigin image-rendering'.split(' ')
75945    );
75946
75947  /**
75948   * Returns {@link fabric.Image} instance from an SVG element
75949   * @static
75950   * @param {SVGElement} element Element to parse
75951   * @param {Object} [options] Options object
75952   * @param {Function} callback Callback to execute when fabric.Image object is created
75953   * @return {fabric.Image} Instance of fabric.Image
75954   */
75955  fabric.Image.fromElement = function(element, callback, options) {
75956    var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES);
75957    fabric.Image.fromURL(parsedAttributes['xlink:href'], callback,
75958      extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));
75959  };
75960  /* _FROM_SVG_END_ */
75961
75962})( true ? exports : 
75962this
vendor: 36,907 bytes, lines 75962-77036
75962);
75963
75964
75965fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {
75966
75967  /**
75968   * @private
75969   * @return {Number} angle value
75970   */
75971  _getAngleValueForStraighten: function() {
75972    var angle = this.angle % 360;
75973    if (angle > 0) {
75974      return Math.round((angle - 1) / 90) * 90;
75975    }
75976    return Math.round(angle / 90) * 90;
75977  },
75978
75979  /**
75980   * Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer)
75981   * @return {fabric.Object} thisArg
75982   * @chainable
75983   */
75984  straighten: function() {
75985    this.rotate(this._getAngleValueForStraighten());
75986    return this;
75987  },
75988
75989  /**
75990   * Same as {@link fabric.Object.prototype.straighten} but with animation
75991   * @param {Object} callbacks Object with callback functions
75992   * @param {Function} [callbacks.onComplete] Invoked on completion
75993   * @param {Function} [callbacks.onChange] Invoked on every step of animation
75994   * @return {fabric.Object} thisArg
75995   * @chainable
75996   */
75997  fxStraighten: function(callbacks) {
75998    callbacks = callbacks || { };
75999
76000    var empty = function() { },
76001        onComplete = callbacks.onComplete || empty,
76002        onChange = callbacks.onChange || empty,
76003        _this = this;
76004
76005    fabric.util.animate({
76006      startValue: this.get('angle'),
76007      endValue: this._getAngleValueForStraighten(),
76008      duration: this.FX_DURATION,
76009      onChange: function(value) {
76010        _this.rotate(value);
76011        onChange();
76012      },
76013      onComplete: function() {
76014        _this.setCoords();
76015        onComplete();
76016      },
76017    });
76018
76019    return this;
76020  }
76021});
76022
76023fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {
76024
76025  /**
76026   * Straightens object, then rerenders canvas
76027   * @param {fabric.Object} object Object to straighten
76028   * @return {fabric.Canvas} thisArg
76029   * @chainable
76030   */
76031  straightenObject: function (object) {
76032    object.straighten();
76033    this.requestRenderAll();
76034    return this;
76035  },
76036
76037  /**
76038   * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated
76039   * @param {fabric.Object} object Object to straighten
76040   * @return {fabric.Canvas} thisArg
76041   * @chainable
76042   */
76043  fxStraightenObject: function (object) {
76044    object.fxStraighten({
76045      onChange: this.requestRenderAllBound
76046    });
76047    return this;
76048  }
76049});
76050
76051
76052(function() {
76053
76054  'use strict';
76055
76056  /**
76057   * Tests if webgl supports certain precision
76058   * @param {WebGL} Canvas WebGL context to test on
76059   * @param {String} Precision to test can be any of following: 'lowp', 'mediump', 'highp'
76060   * @returns {Boolean} Whether the user's browser WebGL supports given precision.
76061   */
76062  function testPrecision(gl, precision){
76063    var fragmentSource = 'precision ' + precision + ' float;\nvoid main(){}';
76064    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
76065    gl.shaderSource(fragmentShader, fragmentSource);
76066    gl.compileShader(fragmentShader);
76067    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
76068      return false;
76069    }
76070    return true;
76071  }
76072
76073  /**
76074   * Indicate whether this filtering backend is supported by the user's browser.
76075   * @param {Number} tileSize check if the tileSize is supported
76076   * @returns {Boolean} Whether the user's browser supports WebGL.
76077   */
76078  fabric.isWebglSupported = function(tileSize) {
76079    if (fabric.isLikelyNode) {
76080      return false;
76081    }
76082    tileSize = tileSize || fabric.WebglFilterBackend.prototype.tileSize;
76083    var canvas = document.createElement('canvas');
76084    var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
76085    var isSupported = false;
76086    // eslint-disable-next-line
76087    if (gl) {
76088      fabric.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
76089      isSupported = fabric.maxTextureSize >= tileSize;
76090      var precisions = ['highp', 'mediump', 'lowp'];
76091      for (var i = 0; i < 3; i++){
76092        if (testPrecision(gl, precisions[i])){
76093          fabric.webGlPrecision = precisions[i];
76094          break;
76095        };
76096      }
76097    }
76098    this.isSupported = isSupported;
76099    return isSupported;
76100  };
76101
76102  fabric.WebglFilterBackend = WebglFilterBackend;
76103
76104  /**
76105   * WebGL filter backend.
76106   */
76107  function WebglFilterBackend(options) {
76108    if (options && options.tileSize) {
76109      this.tileSize = options.tileSize;
76110    }
76111    this.setupGLContext(this.tileSize, this.tileSize);
76112    this.captureGPUInfo();
76113  };
76114
76115  WebglFilterBackend.prototype = /** @lends fabric.WebglFilterBackend.prototype */ {
76116
76117    tileSize: 2048,
76118
76119    /**
76120     * Experimental. This object is a sort of repository of help layers used to avoid
76121     * of recreating them during frequent filtering. If you are previewing a filter with
76122     * a slider you probably do not want to create help layers every filter step.
76123     * in this object there will be appended some canvases, created once, resized sometimes
76124     * cleared never. Clearing is left to the developer.
76125     **/
76126    resources: {
76127
76128    },
76129
76130    /**
76131     * Setup a WebGL context suitable for filtering, and bind any needed event handlers.
76132     */
76133    setupGLContext: function(width, height) {
76134      this.dispose();
76135      this.createWebGLCanvas(width, height);
76136      // eslint-disable-next-line
76137      this.aPosition = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]);
76138      this.chooseFastestCopyGLTo2DMethod(width, height);
76139    },
76140
76141    /**
76142     * Pick a method to copy data from GL context to 2d canvas.  In some browsers using
76143     * putImageData is faster than drawImage for that specific operation.
76144     */
76145    chooseFastestCopyGLTo2DMethod: function(width, height) {
76146      var canMeasurePerf = typeof window.performance !== 'undefined', canUseImageData;
76147      try {
76148        new ImageData(1, 1);
76149        canUseImageData = true;
76150      }
76151      catch (e) {
76152        canUseImageData = false;
76153      }
76154      // eslint-disable-next-line no-undef
76155      var canUseArrayBuffer = typeof ArrayBuffer !== 'undefined';
76156      // eslint-disable-next-line no-undef
76157      var canUseUint8Clamped = typeof Uint8ClampedArray !== 'undefined';
76158
76159      if (!(canMeasurePerf && canUseImageData && canUseArrayBuffer && canUseUint8Clamped)) {
76160        return;
76161      }
76162
76163      var targetCanvas = fabric.util.createCanvasElement();
76164      // eslint-disable-next-line no-undef
76165      var imageBuffer = new ArrayBuffer(width * height * 4);
76166      if (fabric.forceGLPutImageData) {
76167        this.imageBuffer = imageBuffer;
76168        this.copyGLTo2D = copyGLTo2DPutImageData;
76169        return;
76170      }
76171      var testContext = {
76172        imageBuffer: imageBuffer,
76173        destinationWidth: width,
76174        destinationHeight: height,
76175        targetCanvas: targetCanvas
76176      };
76177      var startTime, drawImageTime, putImageDataTime;
76178      targetCanvas.width = width;
76179      targetCanvas.height = height;
76180
76181      startTime = window.performance.now();
76182      copyGLTo2DDrawImage.call(testContext, this.gl, testContext);
76183      drawImageTime = window.performance.now() - startTime;
76184
76185      startTime = window.performance.now();
76186      copyGLTo2DPutImageData.call(testContext, this.gl, testContext);
76187      putImageDataTime = window.performance.now() - startTime;
76188
76189      if (drawImageTime > putImageDataTime) {
76190        this.imageBuffer = imageBuffer;
76191        this.copyGLTo2D = copyGLTo2DPutImageData;
76192      }
76193      else {
76194        this.copyGLTo2D = copyGLTo2DDrawImage;
76195      }
76196    },
76197
76198    /**
76199     * Create a canvas element and associated WebGL context and attaches them as
76200     * class properties to the GLFilterBackend class.
76201     */
76202    createWebGLCanvas: function(width, height) {
76203      var canvas = fabric.util.createCanvasElement();
76204      canvas.width = width;
76205      canvas.height = height;
76206      var glOptions = {
76207            alpha: true,
76208            premultipliedAlpha: false,
76209            depth: false,
76210            stencil: false,
76211            antialias: false
76212          },
76213          gl = canvas.getContext('webgl', glOptions);
76214      if (!gl) {
76215        gl = canvas.getContext('experimental-webgl', glOptions);
76216      }
76217      if (!gl) {
76218        return;
76219      }
76220      gl.clearColor(0, 0, 0, 0);
76221      // this canvas can fire webglcontextlost and webglcontextrestored
76222      this.canvas = canvas;
76223      this.gl = gl;
76224    },
76225
76226    /**
76227     * Attempts to apply the requested filters to the source provided, drawing the filtered output
76228     * to the provided target canvas.
76229     *
76230     * @param {Array} filters The filters to apply.
76231     * @param {HTMLImageElement|HTMLCanvasElement} source The source to be filtered.
76232     * @param {Number} width The width of the source input.
76233     * @param {Number} height The height of the source input.
76234     * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.
76235     * @param {String|undefined} cacheKey A key used to cache resources related to the source. If
76236     * omitted, caching will be skipped.
76237     */
76238    applyFilters: function(filters, source, width, height, targetCanvas, cacheKey) {
76239      var gl = this.gl;
76240      var cachedTexture;
76241      if (cacheKey) {
76242        cachedTexture = this.getCachedTexture(cacheKey, source);
76243      }
76244      var pipelineState = {
76245        originalWidth: source.width || source.originalWidth,
76246        originalHeight: source.height || source.originalHeight,
76247        sourceWidth: width,
76248        sourceHeight: height,
76249        destinationWidth: width,
76250        destinationHeight: height,
76251        context: gl,
76252        sourceTexture: this.createTexture(gl, width, height, !cachedTexture && source),
76253        targetTexture: this.createTexture(gl, width, height),
76254        originalTexture: cachedTexture ||
76255          this.createTexture(gl, width, height, !cachedTexture && source),
76256        passes: filters.length,
76257        webgl: true,
76258        aPosition: this.aPosition,
76259        programCache: this.programCache,
76260        pass: 0,
76261        filterBackend: this,
76262        targetCanvas: targetCanvas
76263      };
76264      var tempFbo = gl.createFramebuffer();
76265      gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo);
76266      filters.forEach(function(filter) { filter && filter.applyTo(pipelineState); });
76267      resizeCanvasIfNeeded(pipelineState);
76268      this.copyGLTo2D(gl, pipelineState);
76269      gl.bindTexture(gl.TEXTURE_2D, null);
76270      gl.deleteTexture(pipelineState.sourceTexture);
76271      gl.deleteTexture(pipelineState.targetTexture);
76272      gl.deleteFramebuffer(tempFbo);
76273      targetCanvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0);
76274      return pipelineState;
76275    },
76276
76277    /**
76278     * Detach event listeners, remove references, and clean up caches.
76279     */
76280    dispose: function() {
76281      if (this.canvas) {
76282        this.canvas = null;
76283        this.gl = null;
76284      }
76285      this.clearWebGLCaches();
76286    },
76287
76288    /**
76289     * Wipe out WebGL-related caches.
76290     */
76291    clearWebGLCaches: function() {
76292      this.programCache = {};
76293      this.textureCache = {};
76294    },
76295
76296    /**
76297     * Create a WebGL texture object.
76298     *
76299     * Accepts specific dimensions to initialize the texture to or a source image.
76300     *
76301     * @param {WebGLRenderingContext} gl The GL context to use for creating the texture.
76302     * @param {Number} width The width to initialize the texture at.
76303     * @param {Number} height The height to initialize the texture.
76304     * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source for the texture data.
76305     * @returns {WebGLTexture}
76306     */
76307    createTexture: function(gl, width, height, textureImageSource) {
76308      var texture = gl.createTexture();
76309      gl.bindTexture(gl.TEXTURE_2D, texture);
76310      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
76311      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
76312      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
76313      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
76314      if (textureImageSource) {
76315        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImageSource);
76316      }
76317      else {
76318        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
76319      }
76320      return texture;
76321    },
76322
76323    /**
76324     * Can be optionally used to get a texture from the cache array
76325     *
76326     * If an existing texture is not found, a new texture is created and cached.
76327     *
76328     * @param {String} uniqueId A cache key to use to find an existing texture.
76329     * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the
76330     * texture cache entry if one does not already exist.
76331     */
76332    getCachedTexture: function(uniqueId, textureImageSource) {
76333      if (this.textureCache[uniqueId]) {
76334        return this.textureCache[uniqueId];
76335      }
76336      else {
76337        var texture = this.createTexture(
76338          this.gl, textureImageSource.width, textureImageSource.height, textureImageSource);
76339        this.textureCache[uniqueId] = texture;
76340        return texture;
76341      }
76342    },
76343
76344    /**
76345     * Clear out cached resources related to a source image that has been
76346     * filtered previously.
76347     *
76348     * @param {String} cacheKey The cache key provided when the source image was filtered.
76349     */
76350    evictCachesForKey: function(cacheKey) {
76351      if (this.textureCache[cacheKey]) {
76352        this.gl.deleteTexture(this.textureCache[cacheKey]);
76353        delete this.textureCache[cacheKey];
76354      }
76355    },
76356
76357    copyGLTo2D: copyGLTo2DDrawImage,
76358
76359    /**
76360     * Attempt to extract GPU information strings from a WebGL context.
76361     *
76362     * Useful information when debugging or blacklisting specific GPUs.
76363     *
76364     * @returns {Object} A GPU info object with renderer and vendor strings.
76365     */
76366    captureGPUInfo: function() {
76367      if (this.gpuInfo) {
76368        return this.gpuInfo;
76369      }
76370      var gl = this.gl, gpuInfo = { renderer: '', vendor: '' };
76371      if (!gl) {
76372        return gpuInfo;
76373      }
76374      var ext = gl.getExtension('WEBGL_debug_renderer_info');
76375      if (ext) {
76376        var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);
76377        var vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);
76378        if (renderer) {
76379          gpuInfo.renderer = renderer.toLowerCase();
76380        }
76381        if (vendor) {
76382          gpuInfo.vendor = vendor.toLowerCase();
76383        }
76384      }
76385      this.gpuInfo = gpuInfo;
76386      return gpuInfo;
76387    },
76388  };
76389})();
76390
76391function resizeCanvasIfNeeded(pipelineState) {
76392  var targetCanvas = pipelineState.targetCanvas,
76393      width = targetCanvas.width, height = targetCanvas.height,
76394      dWidth = pipelineState.destinationWidth,
76395      dHeight = pipelineState.destinationHeight;
76396
76397  if (width !== dWidth || height !== dHeight) {
76398    targetCanvas.width = dWidth;
76399    targetCanvas.height = dHeight;
76400  }
76401}
76402
76403/**
76404 * Copy an input WebGL canvas on to an output 2D canvas.
76405 *
76406 * The WebGL canvas is assumed to be upside down, with the top-left pixel of the
76407 * desired output image appearing in the bottom-left corner of the WebGL canvas.
76408 *
76409 * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.
76410 * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.
76411 * @param {Object} pipelineState The 2D target canvas to copy on to.
76412 */
76413function copyGLTo2DDrawImage(gl, pipelineState) {
76414  var glCanvas = gl.canvas, targetCanvas = pipelineState.targetCanvas,
76415      ctx = targetCanvas.getContext('2d');
76416  ctx.translate(0, targetCanvas.height); // move it down again
76417  ctx.scale(1, -1); // vertical flip
76418  // where is my image on the big glcanvas?
76419  var sourceY = glCanvas.height - targetCanvas.height;
76420  ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0,
76421    targetCanvas.width, targetCanvas.height);
76422}
76423
76424/**
76425 * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData
76426 * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra).
76427 *
76428 * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.
76429 * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.
76430 * @param {Object} pipelineState The 2D target canvas to copy on to.
76431 */
76432function copyGLTo2DPutImageData(gl, pipelineState) {
76433  var targetCanvas = pipelineState.targetCanvas, ctx = targetCanvas.getContext('2d'),
76434      dWidth = pipelineState.destinationWidth,
76435      dHeight = pipelineState.destinationHeight,
76436      numBytes = dWidth * dHeight * 4;
76437
76438  // eslint-disable-next-line no-undef
76439  var u8 = new Uint8Array(this.imageBuffer, 0, numBytes);
76440  // eslint-disable-next-line no-undef
76441  var u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes);
76442
76443  gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8);
76444  var imgData = new ImageData(u8Clamped, dWidth, dHeight);
76445  ctx.putImageData(imgData, 0, 0);
76446}
76447
76448
76449(function() {
76450
76451  'use strict';
76452
76453  var noop = function() {};
76454
76455  fabric.Canvas2dFilterBackend = Canvas2dFilterBackend;
76456
76457  /**
76458   * Canvas 2D filter backend.
76459   */
76460  function Canvas2dFilterBackend() {};
76461
76462  Canvas2dFilterBackend.prototype = /** @lends fabric.Canvas2dFilterBackend.prototype */ {
76463    evictCachesForKey: noop,
76464    dispose: noop,
76465    clearWebGLCaches: noop,
76466
76467    /**
76468     * Experimental. This object is a sort of repository of help layers used to avoid
76469     * of recreating them during frequent filtering. If you are previewing a filter with
76470     * a slider you probably do not want to create help layers every filter step.
76471     * in this object there will be appended some canvases, created once, resized sometimes
76472     * cleared never. Clearing is left to the developer.
76473     **/
76474    resources: {
76475
76476    },
76477
76478    /**
76479     * Apply a set of filters against a source image and draw the filtered output
76480     * to the provided destination canvas.
76481     *
76482     * @param {EnhancedFilter} filters The filter to apply.
76483     * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered.
76484     * @param {Number} sourceWidth The width of the source input.
76485     * @param {Number} sourceHeight The height of the source input.
76486     * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.
76487     */
76488    applyFilters: function(filters, sourceElement, sourceWidth, sourceHeight, targetCanvas) {
76489      var ctx = targetCanvas.getContext('2d');
76490      ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight);
76491      var imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);
76492      var originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);
76493      var pipelineState = {
76494        sourceWidth: sourceWidth,
76495        sourceHeight: sourceHeight,
76496        imageData: imageData,
76497        originalEl: sourceElement,
76498        originalImageData: originalImageData,
76499        canvasEl: targetCanvas,
76500        ctx: ctx,
76501        filterBackend: this,
76502      };
76503      filters.forEach(function(filter) { filter.applyTo(pipelineState); });
76504      if (pipelineState.imageData.width !== sourceWidth || pipelineState.imageData.height !== sourceHeight) {
76505        targetCanvas.width = pipelineState.imageData.width;
76506        targetCanvas.height = pipelineState.imageData.height;
76507      }
76508      ctx.putImageData(pipelineState.imageData, 0, 0);
76509      return pipelineState;
76510    },
76511
76512  };
76513})();
76514
76515
76516/**
76517 * @namespace fabric.Image.filters
76518 * @memberOf fabric.Image
76519 * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters}
76520 * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
76521 */
76522fabric.Image = fabric.Image || { };
76523fabric.Image.filters = fabric.Image.filters || { };
76524
76525/**
76526 * Root filter class from which all filter classes inherit from
76527 * @class fabric.Image.filters.BaseFilter
76528 * @memberOf fabric.Image.filters
76529 */
76530fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Image.filters.BaseFilter.prototype */ {
76531
76532  /**
76533   * Filter type
76534   * @param {String} type
76535   * @default
76536   */
76537  type: 'BaseFilter',
76538
76539  /**
76540   * Array of attributes to send with buffers. do not modify
76541   * @private
76542   */
76543
76544  vertexSource: 'attribute vec2 aPosition;\n' +
76545    'varying vec2 vTexCoord;\n' +
76546    'void main() {\n' +
76547      'vTexCoord = aPosition;\n' +
76548      'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n' +
76549    '}',
76550
76551  fragmentSource: 'precision highp float;\n' +
76552    'varying vec2 vTexCoord;\n' +
76553    'uniform sampler2D uTexture;\n' +
76554    'void main() {\n' +
76555      'gl_FragColor = texture2D(uTexture, vTexCoord);\n' +
76556    '}',
76557
76558  /**
76559   * Constructor
76560   * @param {Object} [options] Options object
76561   */
76562  initialize: function(options) {
76563    if (options) {
76564      this.setOptions(options);
76565    }
76566  },
76567
76568  /**
76569   * Sets filter's properties from options
76570   * @param {Object} [options] Options object
76571   */
76572  setOptions: function(options) {
76573    for (var prop in options) {
76574      this[prop] = options[prop];
76575    }
76576  },
76577
76578  /**
76579   * Compile this filter's shader program.
76580   *
76581   * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation.
76582   * @param {String} fragmentSource fragmentShader source for compilation
76583   * @param {String} vertexSource vertexShader source for compilation
76584   */
76585  createProgram: function(gl, fragmentSource, vertexSource) {
76586    fragmentSource = fragmentSource || this.fragmentSource;
76587    vertexSource = vertexSource || this.vertexSource;
76588    if (fabric.webGlPrecision !== 'highp'){
76589      fragmentSource = fragmentSource.replace(
76590        /precision highp float/g,
76591        'precision ' + fabric.webGlPrecision + ' float'
76592      );
76593    }
76594    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
76595    gl.shaderSource(vertexShader, vertexSource);
76596    gl.compileShader(vertexShader);
76597    if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
76598      throw new Error(
76599        // eslint-disable-next-line prefer-template
76600        'Vertex shader compile error for ' + this.type + ': ' +
76601        gl.getShaderInfoLog(vertexShader)
76602      );
76603    }
76604
76605    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
76606    gl.shaderSource(fragmentShader, fragmentSource);
76607    gl.compileShader(fragmentShader);
76608    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
76609      throw new Error(
76610        // eslint-disable-next-line prefer-template
76611        'Fragment shader compile error for ' + this.type + ': ' +
76612        gl.getShaderInfoLog(fragmentShader)
76613      );
76614    }
76615
76616    var program = gl.createProgram();
76617    gl.attachShader(program, vertexShader);
76618    gl.attachShader(program, fragmentShader);
76619    gl.linkProgram(program);
76620    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
76621      throw new Error(
76622        // eslint-disable-next-line prefer-template
76623        'Shader link error for "${this.type}" ' +
76624        gl.getProgramInfoLog(program)
76625      );
76626    }
76627
76628    var attributeLocations = this.getAttributeLocations(gl, program);
76629    var uniformLocations = this.getUniformLocations(gl, program) || { };
76630    uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW');
76631    uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH');
76632    return {
76633      program: program,
76634      attributeLocations: attributeLocations,
76635      uniformLocations: uniformLocations
76636    };
76637  },
76638
76639  /**
76640   * Return a map of attribute names to WebGLAttributeLocation objects.
76641   *
76642   * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.
76643   * @param {WebGLShaderProgram} program The shader program from which to take attribute locations.
76644   * @returns {Object} A map of attribute names to attribute locations.
76645   */
76646  getAttributeLocations: function(gl, program) {
76647    return {
76648      aPosition: gl.getAttribLocation(program, 'aPosition'),
76649    };
76650  },
76651
76652  /**
76653   * Return a map of uniform names to WebGLUniformLocation objects.
76654   *
76655   * Intended to be overridden by subclasses.
76656   *
76657   * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.
76658   * @param {WebGLShaderProgram} program The shader program from which to take uniform locations.
76659   * @returns {Object} A map of uniform names to uniform locations.
76660   */
76661  getUniformLocations: function (/* gl, program */) {
76662    // in case i do not need any special uniform i need to return an empty object
76663    return { };
76664  },
76665
76666  /**
76667   * Send attribute data from this filter to its shader program on the GPU.
76668   *
76669   * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.
76670   * @param {Object} attributeLocations A map of shader attribute names to their locations.
76671   */
76672  sendAttributeData: function(gl, attributeLocations, aPositionData) {
76673    var attributeLocation = attributeLocations.aPosition;
76674    var buffer = gl.createBuffer();
76675    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
76676    gl.enableVertexAttribArray(attributeLocation);
76677    gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0);
76678    gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW);
76679  },
76680
76681  _setupFrameBuffer: function(options) {
76682    var gl = options.context, width, height;
76683    if (options.passes > 1) {
76684      width = options.destinationWidth;
76685      height = options.destinationHeight;
76686      if (options.sourceWidth !== width || options.sourceHeight !== height) {
76687        gl.deleteTexture(options.targetTexture);
76688        options.targetTexture = options.filterBackend.createTexture(gl, width, height);
76689      }
76690      gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D,
76691        options.targetTexture, 0);
76692    }
76693    else {
76694      // draw last filter on canvas and not to framebuffer.
76695      gl.bindFramebuffer(gl.FRAMEBUFFER, null);
76696      gl.finish();
76697    }
76698  },
76699
76700  _swapTextures: function(options) {
76701    options.passes--;
76702    options.pass++;
76703    var temp = options.targetTexture;
76704    options.targetTexture = options.sourceTexture;
76705    options.sourceTexture = temp;
76706  },
76707
76708  /**
76709   * Generic isNeutral implementation for one parameter based filters.
76710   * Used only in image applyFilters to discard filters that will not have an effect
76711   * on the image
76712   * Other filters may need their own version ( ColorMatrix, HueRotation, gamma, ComposedFilter )
76713   * @param {Object} options
76714   **/
76715  isNeutralState: function(/* options */) {
76716    var main = this.mainParameter,
76717        _class = fabric.Image.filters[this.type].prototype;
76718    if (main) {
76719      if (Array.isArray(_class[main])) {
76720        for (var i = _class[main].length; i--;) {
76721          if (this[main][i] !== _class[main][i]) {
76722            return false;
76723          }
76724        }
76725        return true;
76726      }
76727      else {
76728        return _class[main] === this[main];
76729      }
76730    }
76731    else {
76732      return false;
76733    }
76734  },
76735
76736  /**
76737   * Apply this filter to the input image data provided.
76738   *
76739   * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.
76740   *
76741   * @param {Object} options
76742   * @param {Number} options.passes The number of filters remaining to be executed
76743   * @param {Boolean} options.webgl Whether to use webgl to render the filter.
76744   * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.
76745   * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.
76746   * @param {WebGLRenderingContext} options.context The GL context used for rendering.
76747   * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
76748   */
76749  applyTo: function(options) {
76750    if (options.webgl) {
76751      this._setupFrameBuffer(options);
76752      this.applyToWebGL(options);
76753      this._swapTextures(options);
76754    }
76755    else {
76756      this.applyTo2d(options);
76757    }
76758  },
76759
76760  /**
76761   * Retrieves the cached shader.
76762   * @param {Object} options
76763   * @param {WebGLRenderingContext} options.context The GL context used for rendering.
76764   * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
76765   */
76766  retrieveShader: function(options) {
76767    if (!options.programCache.hasOwnProperty(this.type)) {
76768      options.programCache[this.type] = this.createProgram(options.context);
76769    }
76770    return options.programCache[this.type];
76771  },
76772
76773  /**
76774   * Apply this filter using webgl.
76775   *
76776   * @param {Object} options
76777   * @param {Number} options.passes The number of filters remaining to be executed
76778   * @param {Boolean} options.webgl Whether to use webgl to render the filter.
76779   * @param {WebGLTexture} options.originalTexture The texture of the original input image.
76780   * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.
76781   * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.
76782   * @param {WebGLRenderingContext} options.context The GL context used for rendering.
76783   * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
76784   */
76785  applyToWebGL: function(options) {
76786    var gl = options.context;
76787    var shader = this.retrieveShader(options);
76788    if (options.pass === 0 && options.originalTexture) {
76789      gl.bindTexture(gl.TEXTURE_2D, options.originalTexture);
76790    }
76791    else {
76792      gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);
76793    }
76794    gl.useProgram(shader.program);
76795    this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);
76796
76797    gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);
76798    gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight);
76799
76800    this.sendUniformData(gl, shader.uniformLocations);
76801    gl.viewport(0, 0, options.destinationWidth, options.destinationHeight);
76802    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
76803  },
76804
76805  bindAdditionalTexture: function(gl, texture, textureUnit) {
76806    gl.activeTexture(textureUnit);
76807    gl.bindTexture(gl.TEXTURE_2D, texture);
76808    // reset active texture to 0 as usual
76809    gl.activeTexture(gl.TEXTURE0);
76810  },
76811
76812  unbindAdditionalTexture: function(gl, textureUnit) {
76813    gl.activeTexture(textureUnit);
76814    gl.bindTexture(gl.TEXTURE_2D, null);
76815    gl.activeTexture(gl.TEXTURE0);
76816  },
76817
76818  getMainParameter: function() {
76819    return this[this.mainParameter];
76820  },
76821
76822  setMainParameter: function(value) {
76823    this[this.mainParameter] = value;
76824  },
76825
76826  /**
76827   * Send uniform data from this filter to its shader program on the GPU.
76828   *
76829   * Intended to be overridden by subclasses.
76830   *
76831   * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.
76832   * @param {Object} uniformLocations A map of shader uniform names to their locations.
76833   */
76834  sendUniformData: function(/* gl, uniformLocations */) {
76835    // Intentionally left blank.  Override me in subclasses.
76836  },
76837
76838  /**
76839   * If needed by a 2d filter, this functions can create an helper canvas to be used
76840   * remember that options.targetCanvas is available for use till end of chain.
76841   */
76842  createHelpLayer: function(options) {
76843    if (!options.helpLayer) {
76844      var helpLayer = document.createElement('canvas');
76845      helpLayer.width = options.sourceWidth;
76846      helpLayer.height = options.sourceHeight;
76847      options.helpLayer = helpLayer;
76848    }
76849  },
76850
76851  /**
76852   * Returns object representation of an instance
76853   * @return {Object} Object representation of an instance
76854   */
76855  toObject: function() {
76856    var object = { type: this.type }, mainP = this.mainParameter;
76857    if (mainP) {
76858      object[mainP] = this[mainP];
76859    }
76860    return object;
76861  },
76862
76863  /**
76864   * Returns a JSON representation of an instance
76865   * @return {Object} JSON
76866   */
76867  toJSON: function() {
76868    // delegate, not alias
76869    return this.toObject();
76870  }
76871});
76872
76873fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
76874  var filter = new fabric.Image.filters[object.type](object);
76875  callback && callback(filter);
76876  return filter;
76877};
76878
76879
76880(function(global) {
76881
76882  'use strict';
76883
76884  var fabric  = global.fabric || (global.fabric = { }),
76885      filters = fabric.Image.filters,
76886      createClass = fabric.util.createClass;
76887
76888  /**
76889   * Color Matrix filter class
76890   * @class fabric.Image.filters.ColorMatrix
76891   * @memberOf fabric.Image.filters
76892   * @extends fabric.Image.filters.BaseFilter
76893   * @see {@link fabric.Image.filters.ColorMatrix#initialize} for constructor definition
76894   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
76895   * @see {@Link http://www.webwasp.co.uk/tutorials/219/Color_Matrix_Filter.php}
76896   * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl}
76897   * @example <caption>Kodachrome filter</caption>
76898   * var filter = new fabric.Image.filters.ColorMatrix({
76899   *  matrix: [
76900       1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,
76901       -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,
76902       -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,
76903       0, 0, 0, 1, 0
76904      ]
76905   * });
76906   * object.filters.push(filter);
76907   * object.applyFilters();
76908   */
76909  filters.ColorMatrix = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.ColorMatrix.prototype */ {
76910
76911    /**
76912     * Filter type
76913     * @param {String} type
76914     * @default
76915     */
76916    type: 'ColorMatrix',
76917
76918    fragmentSource: 'precision highp float;\n' +
76919      'uniform sampler2D uTexture;\n' +
76920      'varying vec2 vTexCoord;\n' +
76921      'uniform mat4 uColorMatrix;\n' +
76922      'uniform vec4 uConstants;\n' +
76923      'void main() {\n' +
76924        'vec4 color = texture2D(uTexture, vTexCoord);\n' +
76925        'color *= uColorMatrix;\n' +
76926        'color += uConstants;\n' +
76927        'gl_FragColor = color;\n' +
76928      '}',
76929
76930    /**
76931     * Colormatrix for pixels.
76932     * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning
76933     * outside the -1, 1 range.
76934     * 0.0039215686 is the part of 1 that get translated to 1 in 2d
76935     * @param {Array} matrix array of 20 numbers.
76936     * @default
76937     */
76938    matrix: [
76939      1, 0, 0, 0, 0,
76940      0, 1, 0, 0, 0,
76941      0, 0, 1, 0, 0,
76942      0, 0, 0, 1, 0
76943    ],
76944
76945    mainParameter: 'matrix',
76946
76947    /**
76948     * Lock the colormatrix on the color part, skipping alpha, manly for non webgl scenario
76949     * to save some calculation
76950     */
76951    colorsOnly: true,
76952
76953    /**
76954     * Constructor
76955     * @param {Object} [options] Options object
76956     */
76957    initialize: function(options) {
76958      this.callSuper('initialize', options);
76959      // create a new array instead mutating the prototype with push
76960      this.matrix = this.matrix.slice(0);
76961    },
76962
76963    /**
76964     * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image.
76965     *
76966     * @param {Object} options
76967     * @param {ImageData} options.imageData The Uint8Array to be filtered.
76968     */
76969    applyTo2d: function(options) {
76970      var imageData = options.imageData,
76971          data = imageData.data,
76972          iLen = data.length,
76973          m = this.matrix,
76974          r, g, b, a, i, colorsOnly = this.colorsOnly;
76975
76976      for (i = 0; i < iLen; i += 4) {
76977        r = data[i];
76978        g = data[i + 1];
76979        b = data[i + 2];
76980        if (colorsOnly) {
76981          data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255;
76982          data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255;
76983          data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255;
76984        }
76985        else {
76986          a = data[i + 3];
76987          data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255;
76988          data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255;
76989          data[i + 2] = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255;
76990          data[i + 3] = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255;
76991        }
76992      }
76993    },
76994
76995    /**
76996     * Return WebGL uniform locations for this filter's shader.
76997     *
76998     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
76999     * @param {WebGLShaderProgram} program This filter's compiled shader program.
77000     */
77001    getUniformLocations: function(gl, program) {
77002      return {
77003        uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'),
77004        uConstants: gl.getUniformLocation(program, 'uConstants'),
77005      };
77006    },
77007
77008    /**
77009     * Send data from this filter to its shader program's uniforms.
77010     *
77011     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
77012     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
77013     */
77014    sendUniformData: function(gl, uniformLocations) {
77015      var m = this.matrix,
77016          matrix = [
77017            m[0], m[1], m[2], m[3],
77018            m[5], m[6], m[7], m[8],
77019            m[10], m[11], m[12], m[13],
77020            m[15], m[16], m[17], m[18]
77021          ],
77022          constants = [m[4], m[9], m[14], m[19]];
77023      gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix);
77024      gl.uniform4fv(uniformLocations.uConstants, constants);
77025    },
77026  });
77027
77028  /**
77029   * Returns filter instance from an object representation
77030   * @static
77031   * @param {Object} object Object to create an instance from
77032   * @param {function} [callback] function to invoke after filter creation
77033   * @return {fabric.Image.filters.ColorMatrix} Instance of fabric.Image.filters.ColorMatrix
77034   */
77035  fabric.Image.filters.ColorMatrix.fromObject = fabric.Image.filters.BaseFilter.fromObject;
77036})( true ? exports : 
vendor: 3,618 bytes, lines 77036-77151
77036this);
77037
77038
77039(function(global) {
77040
77041  'use strict';
77042
77043  var fabric  = global.fabric || (global.fabric = { }),
77044      filters = fabric.Image.filters,
77045      createClass = fabric.util.createClass;
77046
77047  /**
77048   * Brightness filter class
77049   * @class fabric.Image.filters.Brightness
77050   * @memberOf fabric.Image.filters
77051   * @extends fabric.Image.filters.BaseFilter
77052   * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition
77053   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
77054   * @example
77055   * var filter = new fabric.Image.filters.Brightness({
77056   *   brightness: 0.05
77057   * });
77058   * object.filters.push(filter);
77059   * object.applyFilters();
77060   */
77061  filters.Brightness = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ {
77062
77063    /**
77064     * Filter type
77065     * @param {String} type
77066     * @default
77067     */
77068    type: 'Brightness',
77069
77070    /**
77071     * Fragment source for the brightness program
77072     */
77073    fragmentSource: 'precision highp float;\n' +
77074      'uniform sampler2D uTexture;\n' +
77075      'uniform float uBrightness;\n' +
77076      'varying vec2 vTexCoord;\n' +
77077      'void main() {\n' +
77078        'vec4 color = texture2D(uTexture, vTexCoord);\n' +
77079        'color.rgb += uBrightness;\n' +
77080        'gl_FragColor = color;\n' +
77081      '}',
77082
77083    /**
77084     * Brightness value, from -1 to 1.
77085     * translated to -255 to 255 for 2d
77086     * 0.0039215686 is the part of 1 that get translated to 1 in 2d
77087     * @param {Number} brightness
77088     * @default
77089     */
77090    brightness: 0,
77091
77092    /**
77093     * Describe the property that is the filter parameter
77094     * @param {String} m
77095     * @default
77096     */
77097    mainParameter: 'brightness',
77098
77099    /**
77100    * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.
77101    *
77102    * @param {Object} options
77103    * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.
77104    */
77105    applyTo2d: function(options) {
77106      if (this.brightness === 0) {
77107        return;
77108      }
77109      var imageData = options.imageData,
77110          data = imageData.data, i, len = data.length,
77111          brightness = Math.round(this.brightness * 255);
77112      for (i = 0; i < len; i += 4) {
77113        data[i] = data[i] + brightness;
77114        data[i + 1] = data[i + 1] + brightness;
77115        data[i + 2] = data[i + 2] + brightness;
77116      }
77117    },
77118
77119    /**
77120     * Return WebGL uniform locations for this filter's shader.
77121     *
77122     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
77123     * @param {WebGLShaderProgram} program This filter's compiled shader program.
77124     */
77125    getUniformLocations: function(gl, program) {
77126      return {
77127        uBrightness: gl.getUniformLocation(program, 'uBrightness'),
77128      };
77129    },
77130
77131    /**
77132     * Send data from this filter to its shader program's uniforms.
77133     *
77134     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
77135     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
77136     */
77137    sendUniformData: function(gl, uniformLocations) {
77138      gl.uniform1f(uniformLocations.uBrightness, this.brightness);
77139    },
77140  });
77141
77142  /**
77143   * Returns filter instance from an object representation
77144   * @static
77145   * @param {Object} object Object to create an instance from
77146   * @param {function} [callback] to be invoked after filter creation
77147   * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness
77148   */
77149  fabric.Image.filters.Brightness.fromObject = fabric.Image.filters.BaseFilter.fromObject;
77150
77151})( true ? exports : this
vendor: 13,109 bytes, lines 77151-77505
77151);
77152
77153
77154(function(global) {
77155
77156  'use strict';
77157
77158  var fabric  = global.fabric || (global.fabric = { }),
77159      extend = fabric.util.object.extend,
77160      filters = fabric.Image.filters,
77161      createClass = fabric.util.createClass;
77162
77163  /**
77164   * Adapted from <a href="http://www.html5rocks.com/en/tutorials/canvas/imagefilters/">html5rocks article</a>
77165   * @class fabric.Image.filters.Convolute
77166   * @memberOf fabric.Image.filters
77167   * @extends fabric.Image.filters.BaseFilter
77168   * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition
77169   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
77170   * @example <caption>Sharpen filter</caption>
77171   * var filter = new fabric.Image.filters.Convolute({
77172   *   matrix: [ 0, -1,  0,
77173   *            -1,  5, -1,
77174   *             0, -1,  0 ]
77175   * });
77176   * object.filters.push(filter);
77177   * object.applyFilters();
77178   * canvas.renderAll();
77179   * @example <caption>Blur filter</caption>
77180   * var filter = new fabric.Image.filters.Convolute({
77181   *   matrix: [ 1/9, 1/9, 1/9,
77182   *             1/9, 1/9, 1/9,
77183   *             1/9, 1/9, 1/9 ]
77184   * });
77185   * object.filters.push(filter);
77186   * object.applyFilters();
77187   * canvas.renderAll();
77188   * @example <caption>Emboss filter</caption>
77189   * var filter = new fabric.Image.filters.Convolute({
77190   *   matrix: [ 1,   1,  1,
77191   *             1, 0.7, -1,
77192   *            -1,  -1, -1 ]
77193   * });
77194   * object.filters.push(filter);
77195   * object.applyFilters();
77196   * canvas.renderAll();
77197   * @example <caption>Emboss filter with opaqueness</caption>
77198   * var filter = new fabric.Image.filters.Convolute({
77199   *   opaque: true,
77200   *   matrix: [ 1,   1,  1,
77201   *             1, 0.7, -1,
77202   *            -1,  -1, -1 ]
77203   * });
77204   * object.filters.push(filter);
77205   * object.applyFilters();
77206   * canvas.renderAll();
77207   */
77208  filters.Convolute = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ {
77209
77210    /**
77211     * Filter type
77212     * @param {String} type
77213     * @default
77214     */
77215    type: 'Convolute',
77216
77217    /*
77218     * Opaque value (true/false)
77219     */
77220    opaque: false,
77221
77222    /*
77223     * matrix for the filter, max 9x9
77224     */
77225    matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0],
77226
77227    /**
77228     * Fragment source for the brightness program
77229     */
77230    fragmentSource: {
77231      Convolute_3_1: 'precision highp float;\n' +
77232        'uniform sampler2D uTexture;\n' +
77233        'uniform float uMatrix[9];\n' +
77234        'uniform float uStepW;\n' +
77235        'uniform float uStepH;\n' +
77236        'varying vec2 vTexCoord;\n' +
77237        'void main() {\n' +
77238          'vec4 color = vec4(0, 0, 0, 0);\n' +
77239          'for (float h = 0.0; h < 3.0; h+=1.0) {\n' +
77240            'for (float w = 0.0; w < 3.0; w+=1.0) {\n' +
77241              'vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\n' +
77242              'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n' +
77243            '}\n' +
77244          '}\n' +
77245          'gl_FragColor = color;\n' +
77246        '}',
77247      Convolute_3_0: 'precision highp float;\n' +
77248        'uniform sampler2D uTexture;\n' +
77249        'uniform float uMatrix[9];\n' +
77250        'uniform float uStepW;\n' +
77251        'uniform float uStepH;\n' +
77252        'varying vec2 vTexCoord;\n' +
77253        'void main() {\n' +
77254          'vec4 color = vec4(0, 0, 0, 1);\n' +
77255          'for (float h = 0.0; h < 3.0; h+=1.0) {\n' +
77256            'for (float w = 0.0; w < 3.0; w+=1.0) {\n' +
77257              'vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\n' +
77258              'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n' +
77259            '}\n' +
77260          '}\n' +
77261          'float alpha = texture2D(uTexture, vTexCoord).a;\n' +
77262          'gl_FragColor = color;\n' +
77263          'gl_FragColor.a = alpha;\n' +
77264        '}',
77265      Convolute_5_1: 'precision highp float;\n' +
77266        'uniform sampler2D uTexture;\n' +
77267        'uniform float uMatrix[25];\n' +
77268        'uniform float uStepW;\n' +
77269        'uniform float uStepH;\n' +
77270        'varying vec2 vTexCoord;\n' +
77271        'void main() {\n' +
77272          'vec4 color = vec4(0, 0, 0, 0);\n' +
77273          'for (float h = 0.0; h < 5.0; h+=1.0) {\n' +
77274            'for (float w = 0.0; w < 5.0; w+=1.0) {\n' +
77275              'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n' +
77276              'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n' +
77277            '}\n' +
77278          '}\n' +
77279          'gl_FragColor = color;\n' +
77280        '}',
77281      Convolute_5_0: 'precision highp float;\n' +
77282        'uniform sampler2D uTexture;\n' +
77283        'uniform float uMatrix[25];\n' +
77284        'uniform float uStepW;\n' +
77285        'uniform float uStepH;\n' +
77286        'varying vec2 vTexCoord;\n' +
77287        'void main() {\n' +
77288          'vec4 color = vec4(0, 0, 0, 1);\n' +
77289          'for (float h = 0.0; h < 5.0; h+=1.0) {\n' +
77290            'for (float w = 0.0; w < 5.0; w+=1.0) {\n' +
77291              'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n' +
77292              'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n' +
77293            '}\n' +
77294          '}\n' +
77295          'float alpha = texture2D(uTexture, vTexCoord).a;\n' +
77296          'gl_FragColor = color;\n' +
77297          'gl_FragColor.a = alpha;\n' +
77298        '}',
77299      Convolute_7_1: 'precision highp float;\n' +
77300        'uniform sampler2D uTexture;\n' +
77301        'uniform float uMatrix[49];\n' +
77302        'uniform float uStepW;\n' +
77303        'uniform float uStepH;\n' +
77304        'varying vec2 vTexCoord;\n' +
77305        'void main() {\n' +
77306          'vec4 color = vec4(0, 0, 0, 0);\n' +
77307          'for (float h = 0.0; h < 7.0; h+=1.0) {\n' +
77308            'for (float w = 0.0; w < 7.0; w+=1.0) {\n' +
77309              'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n' +
77310              'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n' +
77311            '}\n' +
77312          '}\n' +
77313          'gl_FragColor = color;\n' +
77314        '}',
77315      Convolute_7_0: 'precision highp float;\n' +
77316        'uniform sampler2D uTexture;\n' +
77317        'uniform float uMatrix[49];\n' +
77318        'uniform float uStepW;\n' +
77319        'uniform float uStepH;\n' +
77320        'varying vec2 vTexCoord;\n' +
77321        'void main() {\n' +
77322          'vec4 color = vec4(0, 0, 0, 1);\n' +
77323          'for (float h = 0.0; h < 7.0; h+=1.0) {\n' +
77324            'for (float w = 0.0; w < 7.0; w+=1.0) {\n' +
77325              'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n' +
77326              'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n' +
77327            '}\n' +
77328          '}\n' +
77329          'float alpha = texture2D(uTexture, vTexCoord).a;\n' +
77330          'gl_FragColor = color;\n' +
77331          'gl_FragColor.a = alpha;\n' +
77332        '}',
77333      Convolute_9_1: 'precision highp float;\n' +
77334        'uniform sampler2D uTexture;\n' +
77335        'uniform float uMatrix[81];\n' +
77336        'uniform float uStepW;\n' +
77337        'uniform float uStepH;\n' +
77338        'varying vec2 vTexCoord;\n' +
77339        'void main() {\n' +
77340          'vec4 color = vec4(0, 0, 0, 0);\n' +
77341          'for (float h = 0.0; h < 9.0; h+=1.0) {\n' +
77342            'for (float w = 0.0; w < 9.0; w+=1.0) {\n' +
77343              'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n' +
77344              'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n' +
77345            '}\n' +
77346          '}\n' +
77347          'gl_FragColor = color;\n' +
77348        '}',
77349      Convolute_9_0: 'precision highp float;\n' +
77350        'uniform sampler2D uTexture;\n' +
77351        'uniform float uMatrix[81];\n' +
77352        'uniform float uStepW;\n' +
77353        'uniform float uStepH;\n' +
77354        'varying vec2 vTexCoord;\n' +
77355        'void main() {\n' +
77356          'vec4 color = vec4(0, 0, 0, 1);\n' +
77357          'for (float h = 0.0; h < 9.0; h+=1.0) {\n' +
77358            'for (float w = 0.0; w < 9.0; w+=1.0) {\n' +
77359              'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n' +
77360              'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n' +
77361            '}\n' +
77362          '}\n' +
77363          'float alpha = texture2D(uTexture, vTexCoord).a;\n' +
77364          'gl_FragColor = color;\n' +
77365          'gl_FragColor.a = alpha;\n' +
77366        '}',
77367    },
77368
77369    /**
77370     * Constructor
77371     * @memberOf fabric.Image.filters.Convolute.prototype
77372     * @param {Object} [options] Options object
77373     * @param {Boolean} [options.opaque=false] Opaque value (true/false)
77374     * @param {Array} [options.matrix] Filter matrix
77375     */
77376
77377
77378    /**
77379    * Retrieves the cached shader.
77380    * @param {Object} options
77381    * @param {WebGLRenderingContext} options.context The GL context used for rendering.
77382    * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
77383    */
77384    retrieveShader: function(options) {
77385      var size = Math.sqrt(this.matrix.length);
77386      var cacheKey = this.type + '_' + size + '_' + (this.opaque ? 1 : 0);
77387      var shaderSource = this.fragmentSource[cacheKey];
77388      if (!options.programCache.hasOwnProperty(cacheKey)) {
77389        options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);
77390      }
77391      return options.programCache[cacheKey];
77392    },
77393
77394    /**
77395     * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.
77396     *
77397     * @param {Object} options
77398     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.
77399     */
77400    applyTo2d: function(options) {
77401      var imageData = options.imageData,
77402          data = imageData.data,
77403          weights = this.matrix,
77404          side = Math.round(Math.sqrt(weights.length)),
77405          halfSide = Math.floor(side / 2),
77406          sw = imageData.width,
77407          sh = imageData.height,
77408          output = options.ctx.createImageData(sw, sh),
77409          dst = output.data,
77410          // go through the destination image pixels
77411          alphaFac = this.opaque ? 1 : 0,
77412          r, g, b, a, dstOff,
77413          scx, scy, srcOff, wt,
77414          x, y, cx, cy;
77415
77416      for (y = 0; y < sh; y++) {
77417        for (x = 0; x < sw; x++) {
77418          dstOff = (y * sw + x) * 4;
77419          // calculate the weighed sum of the source image pixels that
77420          // fall under the convolution matrix
77421          r = 0; g = 0; b = 0; a = 0;
77422
77423          for (cy = 0; cy < side; cy++) {
77424            for (cx = 0; cx < side; cx++) {
77425              scy = y + cy - halfSide;
77426              scx = x + cx - halfSide;
77427
77428              // eslint-disable-next-line max-depth
77429              if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) {
77430                continue;
77431              }
77432
77433              srcOff = (scy * sw + scx) * 4;
77434              wt = weights[cy * side + cx];
77435
77436              r += data[srcOff] * wt;
77437              g += data[srcOff + 1] * wt;
77438              b += data[srcOff + 2] * wt;
77439              // eslint-disable-next-line max-depth
77440              if (!alphaFac) {
77441                a += data[srcOff + 3] * wt;
77442              }
77443            }
77444          }
77445          dst[dstOff] = r;
77446          dst[dstOff + 1] = g;
77447          dst[dstOff + 2] = b;
77448          if (!alphaFac) {
77449            dst[dstOff + 3] = a;
77450          }
77451          else {
77452            dst[dstOff + 3] = data[dstOff + 3];
77453          }
77454        }
77455      }
77456      options.imageData = output;
77457    },
77458
77459    /**
77460     * Return WebGL uniform locations for this filter's shader.
77461     *
77462     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
77463     * @param {WebGLShaderProgram} program This filter's compiled shader program.
77464     */
77465    getUniformLocations: function(gl, program) {
77466      return {
77467        uMatrix: gl.getUniformLocation(program, 'uMatrix'),
77468        uOpaque: gl.getUniformLocation(program, 'uOpaque'),
77469        uHalfSize: gl.getUniformLocation(program, 'uHalfSize'),
77470        uSize: gl.getUniformLocation(program, 'uSize'),
77471      };
77472    },
77473
77474    /**
77475     * Send data from this filter to its shader program's uniforms.
77476     *
77477     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
77478     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
77479     */
77480    sendUniformData: function(gl, uniformLocations) {
77481      gl.uniform1fv(uniformLocations.uMatrix, this.matrix);
77482    },
77483
77484    /**
77485     * Returns object representation of an instance
77486     * @return {Object} Object representation of an instance
77487     */
77488    toObject: function() {
77489      return extend(this.callSuper('toObject'), {
77490        opaque: this.opaque,
77491        matrix: this.matrix
77492      });
77493    }
77494  });
77495
77496  /**
77497   * Returns filter instance from an object representation
77498   * @static
77499   * @param {Object} object Object to create an instance from
77500   * @param {function} [callback] to be invoked after filter creation
77501   * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute
77502   */
77503  fabric.Image.filters.Convolute.fromObject = fabric.Image.filters.BaseFilter.fromObject;
77504
77505})( true ? exports : 
vendor: 32,113 bytes, lines 77505-78527
77505this);
77506
77507
77508(function(global) {
77509
77510  'use strict';
77511
77512  var fabric  = global.fabric || (global.fabric = { }),
77513      filters = fabric.Image.filters,
77514      createClass = fabric.util.createClass;
77515
77516  /**
77517   * Grayscale image filter class
77518   * @class fabric.Image.filters.Grayscale
77519   * @memberOf fabric.Image.filters
77520   * @extends fabric.Image.filters.BaseFilter
77521   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
77522   * @example
77523   * var filter = new fabric.Image.filters.Grayscale();
77524   * object.filters.push(filter);
77525   * object.applyFilters();
77526   */
77527  filters.Grayscale = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ {
77528
77529    /**
77530     * Filter type
77531     * @param {String} type
77532     * @default
77533     */
77534    type: 'Grayscale',
77535
77536    fragmentSource: {
77537      average: 'precision highp float;\n' +
77538        'uniform sampler2D uTexture;\n' +
77539        'varying vec2 vTexCoord;\n' +
77540        'void main() {\n' +
77541          'vec4 color = texture2D(uTexture, vTexCoord);\n' +
77542          'float average = (color.r + color.b + color.g) / 3.0;\n' +
77543          'gl_FragColor = vec4(average, average, average, color.a);\n' +
77544        '}',
77545      lightness: 'precision highp float;\n' +
77546        'uniform sampler2D uTexture;\n' +
77547        'uniform int uMode;\n' +
77548        'varying vec2 vTexCoord;\n' +
77549        'void main() {\n' +
77550          'vec4 col = texture2D(uTexture, vTexCoord);\n' +
77551          'float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\n' +
77552          'gl_FragColor = vec4(average, average, average, col.a);\n' +
77553        '}',
77554      luminosity: 'precision highp float;\n' +
77555        'uniform sampler2D uTexture;\n' +
77556        'uniform int uMode;\n' +
77557        'varying vec2 vTexCoord;\n' +
77558        'void main() {\n' +
77559          'vec4 col = texture2D(uTexture, vTexCoord);\n' +
77560          'float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\n' +
77561          'gl_FragColor = vec4(average, average, average, col.a);\n' +
77562        '}',
77563    },
77564
77565
77566    /**
77567     * Grayscale mode, between 'average', 'lightness', 'luminosity'
77568     * @param {String} type
77569     * @default
77570     */
77571    mode: 'average',
77572
77573    mainParameter: 'mode',
77574
77575    /**
77576     * Apply the Grayscale operation to a Uint8Array representing the pixels of an image.
77577     *
77578     * @param {Object} options
77579     * @param {ImageData} options.imageData The Uint8Array to be filtered.
77580     */
77581    applyTo2d: function(options) {
77582      var imageData = options.imageData,
77583          data = imageData.data, i,
77584          len = data.length, value,
77585          mode = this.mode;
77586      for (i = 0; i < len; i += 4) {
77587        if (mode === 'average') {
77588          value = (data[i] + data[i + 1] + data[i + 2]) / 3;
77589        }
77590        else if (mode === 'lightness') {
77591          value = (Math.min(data[i], data[i + 1], data[i + 2]) +
77592            Math.max(data[i], data[i + 1], data[i + 2])) / 2;
77593        }
77594        else if (mode === 'luminosity') {
77595          value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];
77596        }
77597        data[i] = value;
77598        data[i + 1] = value;
77599        data[i + 2] = value;
77600      }
77601    },
77602
77603    /**
77604     * Retrieves the cached shader.
77605     * @param {Object} options
77606     * @param {WebGLRenderingContext} options.context The GL context used for rendering.
77607     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
77608     */
77609    retrieveShader: function(options) {
77610      var cacheKey = this.type + '_' + this.mode;
77611      if (!options.programCache.hasOwnProperty(cacheKey)) {
77612        var shaderSource = this.fragmentSource[this.mode];
77613        options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);
77614      }
77615      return options.programCache[cacheKey];
77616    },
77617
77618    /**
77619     * Return WebGL uniform locations for this filter's shader.
77620     *
77621     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
77622     * @param {WebGLShaderProgram} program This filter's compiled shader program.
77623     */
77624    getUniformLocations: function(gl, program) {
77625      return {
77626        uMode: gl.getUniformLocation(program, 'uMode'),
77627      };
77628    },
77629
77630    /**
77631     * Send data from this filter to its shader program's uniforms.
77632     *
77633     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
77634     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
77635     */
77636    sendUniformData: function(gl, uniformLocations) {
77637      // default average mode.
77638      var mode = 1;
77639      gl.uniform1i(uniformLocations.uMode, mode);
77640    },
77641
77642    /**
77643     * Grayscale filter isNeutralState implementation
77644     * The filter is never neutral
77645     * on the image
77646     **/
77647    isNeutralState: function() {
77648      return false;
77649    },
77650  });
77651
77652  /**
77653   * Returns filter instance from an object representation
77654   * @static
77655   * @param {Object} object Object to create an instance from
77656   * @param {function} [callback] to be invoked after filter creation
77657   * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale
77658   */
77659  fabric.Image.filters.Grayscale.fromObject = fabric.Image.filters.BaseFilter.fromObject;
77660
77661})( true ? exports : this);
77662
77663
77664(function(global) {
77665
77666  'use strict';
77667
77668  var fabric  = global.fabric || (global.fabric = { }),
77669      filters = fabric.Image.filters,
77670      createClass = fabric.util.createClass;
77671
77672  /**
77673   * Invert filter class
77674   * @class fabric.Image.filters.Invert
77675   * @memberOf fabric.Image.filters
77676   * @extends fabric.Image.filters.BaseFilter
77677   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
77678   * @example
77679   * var filter = new fabric.Image.filters.Invert();
77680   * object.filters.push(filter);
77681   * object.applyFilters(canvas.renderAll.bind(canvas));
77682   */
77683  filters.Invert = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ {
77684
77685    /**
77686     * Filter type
77687     * @param {String} type
77688     * @default
77689     */
77690    type: 'Invert',
77691
77692    fragmentSource: 'precision highp float;\n' +
77693      'uniform sampler2D uTexture;\n' +
77694      'uniform int uInvert;\n' +
77695      'varying vec2 vTexCoord;\n' +
77696      'void main() {\n' +
77697        'vec4 color = texture2D(uTexture, vTexCoord);\n' +
77698        'if (uInvert == 1) {\n' +
77699          'gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n' +
77700        '} else {\n' +
77701          'gl_FragColor = color;\n' +
77702        '}\n' +
77703      '}',
77704
77705    /**
77706     * Filter invert. if false, does nothing
77707     * @param {Boolean} invert
77708     * @default
77709     */
77710    invert: true,
77711
77712    mainParameter: 'invert',
77713
77714    /**
77715     * Apply the Invert operation to a Uint8Array representing the pixels of an image.
77716     *
77717     * @param {Object} options
77718     * @param {ImageData} options.imageData The Uint8Array to be filtered.
77719     */
77720    applyTo2d: function(options) {
77721      var imageData = options.imageData,
77722          data = imageData.data, i,
77723          len = data.length;
77724      for (i = 0; i < len; i += 4) {
77725        data[i] = 255 - data[i];
77726        data[i + 1] = 255 - data[i + 1];
77727        data[i + 2] = 255 - data[i + 2];
77728      }
77729    },
77730
77731    /**
77732     * Invert filter isNeutralState implementation
77733     * Used only in image applyFilters to discard filters that will not have an effect
77734     * on the image
77735     * @param {Object} options
77736     **/
77737    isNeutralState: function() {
77738      return !this.invert;
77739    },
77740
77741    /**
77742     * Return WebGL uniform locations for this filter's shader.
77743     *
77744     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
77745     * @param {WebGLShaderProgram} program This filter's compiled shader program.
77746     */
77747    getUniformLocations: function(gl, program) {
77748      return {
77749        uInvert: gl.getUniformLocation(program, 'uInvert'),
77750      };
77751    },
77752
77753    /**
77754     * Send data from this filter to its shader program's uniforms.
77755     *
77756     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
77757     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
77758     */
77759    sendUniformData: function(gl, uniformLocations) {
77760      gl.uniform1i(uniformLocations.uInvert, this.invert);
77761    },
77762  });
77763
77764  /**
77765   * Returns filter instance from an object representation
77766   * @static
77767   * @param {Object} object Object to create an instance from
77768   * @param {function} [callback] to be invoked after filter creation
77769   * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert
77770   */
77771  fabric.Image.filters.Invert.fromObject = fabric.Image.filters.BaseFilter.fromObject;
77772
77773
77774})( true ? exports : this);
77775
77776
77777(function(global) {
77778
77779  'use strict';
77780
77781  var fabric  = global.fabric || (global.fabric = { }),
77782      extend = fabric.util.object.extend,
77783      filters = fabric.Image.filters,
77784      createClass = fabric.util.createClass;
77785
77786  /**
77787   * Noise filter class
77788   * @class fabric.Image.filters.Noise
77789   * @memberOf fabric.Image.filters
77790   * @extends fabric.Image.filters.BaseFilter
77791   * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition
77792   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
77793   * @example
77794   * var filter = new fabric.Image.filters.Noise({
77795   *   noise: 700
77796   * });
77797   * object.filters.push(filter);
77798   * object.applyFilters();
77799   * canvas.renderAll();
77800   */
77801  filters.Noise = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ {
77802
77803    /**
77804     * Filter type
77805     * @param {String} type
77806     * @default
77807     */
77808    type: 'Noise',
77809
77810    /**
77811     * Fragment source for the noise program
77812     */
77813    fragmentSource: 'precision highp float;\n' +
77814      'uniform sampler2D uTexture;\n' +
77815      'uniform float uStepH;\n' +
77816      'uniform float uNoise;\n' +
77817      'uniform float uSeed;\n' +
77818      'varying vec2 vTexCoord;\n' +
77819      'float rand(vec2 co, float seed, float vScale) {\n' +
77820        'return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n' +
77821      '}\n' +
77822      'void main() {\n' +
77823        'vec4 color = texture2D(uTexture, vTexCoord);\n' +
77824        'color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\n' +
77825        'gl_FragColor = color;\n' +
77826      '}',
77827
77828    /**
77829     * Describe the property that is the filter parameter
77830     * @param {String} m
77831     * @default
77832     */
77833    mainParameter: 'noise',
77834
77835    /**
77836     * Noise value, from
77837     * @param {Number} noise
77838     * @default
77839     */
77840    noise: 0,
77841
77842    /**
77843     * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.
77844     *
77845     * @param {Object} options
77846     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.
77847     */
77848    applyTo2d: function(options) {
77849      if (this.noise === 0) {
77850        return;
77851      }
77852      var imageData = options.imageData,
77853          data = imageData.data, i, len = data.length,
77854          noise = this.noise, rand;
77855
77856      for (i = 0, len = data.length; i < len; i += 4) {
77857
77858        rand = (0.5 - Math.random()) * noise;
77859
77860        data[i] += rand;
77861        data[i + 1] += rand;
77862        data[i + 2] += rand;
77863      }
77864    },
77865
77866    /**
77867     * Return WebGL uniform locations for this filter's shader.
77868     *
77869     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
77870     * @param {WebGLShaderProgram} program This filter's compiled shader program.
77871     */
77872    getUniformLocations: function(gl, program) {
77873      return {
77874        uNoise: gl.getUniformLocation(program, 'uNoise'),
77875        uSeed: gl.getUniformLocation(program, 'uSeed'),
77876      };
77877    },
77878
77879    /**
77880     * Send data from this filter to its shader program's uniforms.
77881     *
77882     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
77883     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
77884     */
77885    sendUniformData: function(gl, uniformLocations) {
77886      gl.uniform1f(uniformLocations.uNoise, this.noise / 255);
77887      gl.uniform1f(uniformLocations.uSeed, Math.random());
77888    },
77889
77890    /**
77891     * Returns object representation of an instance
77892     * @return {Object} Object representation of an instance
77893     */
77894    toObject: function() {
77895      return extend(this.callSuper('toObject'), {
77896        noise: this.noise
77897      });
77898    }
77899  });
77900
77901  /**
77902   * Returns filter instance from an object representation
77903   * @static
77904   * @param {Object} object Object to create an instance from
77905   * @param {Function} [callback] to be invoked after filter creation
77906   * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise
77907   */
77908  fabric.Image.filters.Noise.fromObject = fabric.Image.filters.BaseFilter.fromObject;
77909
77910})( true ? exports : this);
77911
77912
77913(function(global) {
77914
77915  'use strict';
77916
77917  var fabric  = global.fabric || (global.fabric = { }),
77918      filters = fabric.Image.filters,
77919      createClass = fabric.util.createClass;
77920
77921  /**
77922   * Pixelate filter class
77923   * @class fabric.Image.filters.Pixelate
77924   * @memberOf fabric.Image.filters
77925   * @extends fabric.Image.filters.BaseFilter
77926   * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition
77927   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
77928   * @example
77929   * var filter = new fabric.Image.filters.Pixelate({
77930   *   blocksize: 8
77931   * });
77932   * object.filters.push(filter);
77933   * object.applyFilters();
77934   */
77935  filters.Pixelate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ {
77936
77937    /**
77938     * Filter type
77939     * @param {String} type
77940     * @default
77941     */
77942    type: 'Pixelate',
77943
77944    blocksize: 4,
77945
77946    mainParameter: 'blocksize',
77947
77948    /**
77949     * Fragment source for the Pixelate program
77950     */
77951    fragmentSource: 'precision highp float;\n' +
77952      'uniform sampler2D uTexture;\n' +
77953      'uniform float uBlocksize;\n' +
77954      'uniform float uStepW;\n' +
77955      'uniform float uStepH;\n' +
77956      'varying vec2 vTexCoord;\n' +
77957      'void main() {\n' +
77958        'float blockW = uBlocksize * uStepW;\n' +
77959        'float blockH = uBlocksize * uStepW;\n' +
77960        'int posX = int(vTexCoord.x / blockW);\n' +
77961        'int posY = int(vTexCoord.y / blockH);\n' +
77962        'float fposX = float(posX);\n' +
77963        'float fposY = float(posY);\n' +
77964        'vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\n' +
77965        'vec4 color = texture2D(uTexture, squareCoords);\n' +
77966        'gl_FragColor = color;\n' +
77967      '}',
77968
77969    /**
77970     * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image.
77971     *
77972     * @param {Object} options
77973     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.
77974     */
77975    applyTo2d: function(options) {
77976      var imageData = options.imageData,
77977          data = imageData.data,
77978          iLen = imageData.height,
77979          jLen = imageData.width,
77980          index, i, j, r, g, b, a,
77981          _i, _j, _iLen, _jLen;
77982
77983      for (i = 0; i < iLen; i += this.blocksize) {
77984        for (j = 0; j < jLen; j += this.blocksize) {
77985
77986          index = (i * 4) * jLen + (j * 4);
77987
77988          r = data[index];
77989          g = data[index + 1];
77990          b = data[index + 2];
77991          a = data[index + 3];
77992
77993          _iLen = Math.min(i + this.blocksize, iLen);
77994          _jLen = Math.min(j + this.blocksize, jLen);
77995          for (_i = i; _i < _iLen; _i++) {
77996            for (_j = j; _j < _jLen; _j++) {
77997              index = (_i * 4) * jLen + (_j * 4);
77998              data[index] = r;
77999              data[index + 1] = g;
78000              data[index + 2] = b;
78001              data[index + 3] = a;
78002            }
78003          }
78004        }
78005      }
78006    },
78007
78008    /**
78009     * Indicate when the filter is not gonna apply changes to the image
78010     **/
78011    isNeutralState: function() {
78012      return this.blocksize === 1;
78013    },
78014
78015    /**
78016     * Return WebGL uniform locations for this filter's shader.
78017     *
78018     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
78019     * @param {WebGLShaderProgram} program This filter's compiled shader program.
78020     */
78021    getUniformLocations: function(gl, program) {
78022      return {
78023        uBlocksize: gl.getUniformLocation(program, 'uBlocksize'),
78024        uStepW: gl.getUniformLocation(program, 'uStepW'),
78025        uStepH: gl.getUniformLocation(program, 'uStepH'),
78026      };
78027    },
78028
78029    /**
78030     * Send data from this filter to its shader program's uniforms.
78031     *
78032     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
78033     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
78034     */
78035    sendUniformData: function(gl, uniformLocations) {
78036      gl.uniform1f(uniformLocations.uBlocksize, this.blocksize);
78037    },
78038  });
78039
78040  /**
78041   * Returns filter instance from an object representation
78042   * @static
78043   * @param {Object} object Object to create an instance from
78044   * @param {Function} [callback] to be invoked after filter creation
78045   * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate
78046   */
78047  fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject;
78048
78049})( true ? exports : this);
78050
78051
78052(function(global) {
78053
78054  'use strict';
78055
78056  var fabric  = global.fabric || (global.fabric = { }),
78057      extend = fabric.util.object.extend,
78058      filters = fabric.Image.filters,
78059      createClass = fabric.util.createClass;
78060
78061  /**
78062   * Remove white filter class
78063   * @class fabric.Image.filters.RemoveColor
78064   * @memberOf fabric.Image.filters
78065   * @extends fabric.Image.filters.BaseFilter
78066   * @see {@link fabric.Image.filters.RemoveColor#initialize} for constructor definition
78067   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
78068   * @example
78069   * var filter = new fabric.Image.filters.RemoveColor({
78070   *   threshold: 0.2,
78071   * });
78072   * object.filters.push(filter);
78073   * object.applyFilters();
78074   * canvas.renderAll();
78075   */
78076  filters.RemoveColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.RemoveColor.prototype */ {
78077
78078    /**
78079     * Filter type
78080     * @param {String} type
78081     * @default
78082     */
78083    type: 'RemoveColor',
78084
78085    /**
78086     * Color to remove, in any format understood by fabric.Color.
78087     * @param {String} type
78088     * @default
78089     */
78090    color: '#FFFFFF',
78091
78092    /**
78093     * Fragment source for the brightness program
78094     */
78095    fragmentSource: 'precision highp float;\n' +
78096      'uniform sampler2D uTexture;\n' +
78097      'uniform vec4 uLow;\n' +
78098      'uniform vec4 uHigh;\n' +
78099      'varying vec2 vTexCoord;\n' +
78100      'void main() {\n' +
78101        'gl_FragColor = texture2D(uTexture, vTexCoord);\n' +
78102        'if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\n' +
78103          'gl_FragColor.a = 0.0;\n' +
78104        '}\n' +
78105      '}',
78106
78107    /**
78108     * distance to actual color, as value up or down from each r,g,b
78109     * between 0 and 1
78110     **/
78111    distance: 0.02,
78112
78113    /**
78114     * For color to remove inside distance, use alpha channel for a smoother deletion
78115     * NOT IMPLEMENTED YET
78116     **/
78117    useAlpha: false,
78118
78119    /**
78120     * Constructor
78121     * @memberOf fabric.Image.filters.RemoveWhite.prototype
78122     * @param {Object} [options] Options object
78123     * @param {Number} [options.color=#RRGGBB] Threshold value
78124     * @param {Number} [options.distance=10] Distance value
78125     */
78126
78127    /**
78128     * Applies filter to canvas element
78129     * @param {Object} canvasEl Canvas element to apply filter to
78130     */
78131    applyTo2d: function(options) {
78132      var imageData = options.imageData,
78133          data = imageData.data, i,
78134          distance = this.distance * 255,
78135          r, g, b,
78136          source = new fabric.Color(this.color).getSource(),
78137          lowC = [
78138            source[0] - distance,
78139            source[1] - distance,
78140            source[2] - distance,
78141          ],
78142          highC = [
78143            source[0] + distance,
78144            source[1] + distance,
78145            source[2] + distance,
78146          ];
78147
78148
78149      for (i = 0; i < data.length; i += 4) {
78150        r = data[i];
78151        g = data[i + 1];
78152        b = data[i + 2];
78153
78154        if (r > lowC[0] &&
78155            g > lowC[1] &&
78156            b > lowC[2] &&
78157            r < highC[0] &&
78158            g < highC[1] &&
78159            b < highC[2]) {
78160          data[i + 3] = 0;
78161        }
78162      }
78163    },
78164
78165    /**
78166     * Return WebGL uniform locations for this filter's shader.
78167     *
78168     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
78169     * @param {WebGLShaderProgram} program This filter's compiled shader program.
78170     */
78171    getUniformLocations: function(gl, program) {
78172      return {
78173        uLow: gl.getUniformLocation(program, 'uLow'),
78174        uHigh: gl.getUniformLocation(program, 'uHigh'),
78175      };
78176    },
78177
78178    /**
78179     * Send data from this filter to its shader program's uniforms.
78180     *
78181     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
78182     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
78183     */
78184    sendUniformData: function(gl, uniformLocations) {
78185      var source = new fabric.Color(this.color).getSource(),
78186          distance = parseFloat(this.distance),
78187          lowC = [
78188            0 + source[0] / 255 - distance,
78189            0 + source[1] / 255 - distance,
78190            0 + source[2] / 255 - distance,
78191            1
78192          ],
78193          highC = [
78194            source[0] / 255 + distance,
78195            source[1] / 255 + distance,
78196            source[2] / 255 + distance,
78197            1
78198          ];
78199      gl.uniform4fv(uniformLocations.uLow, lowC);
78200      gl.uniform4fv(uniformLocations.uHigh, highC);
78201    },
78202
78203    /**
78204     * Returns object representation of an instance
78205     * @return {Object} Object representation of an instance
78206     */
78207    toObject: function() {
78208      return extend(this.callSuper('toObject'), {
78209        color: this.color,
78210        distance: this.distance
78211      });
78212    }
78213  });
78214
78215  /**
78216   * Returns filter instance from an object representation
78217   * @static
78218   * @param {Object} object Object to create an instance from
78219   * @param {Function} [callback] to be invoked after filter creation
78220   * @return {fabric.Image.filters.RemoveColor} Instance of fabric.Image.filters.RemoveWhite
78221   */
78222  fabric.Image.filters.RemoveColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;
78223
78224})( true ? exports : this);
78225
78226
78227(function(global) {
78228
78229  'use strict';
78230
78231  var fabric  = global.fabric || (global.fabric = { }),
78232      filters = fabric.Image.filters,
78233      createClass = fabric.util.createClass;
78234
78235  var matrices = {
78236    Brownie: [
78237      0.59970,0.34553,-0.27082,0,0.186,
78238      -0.03770,0.86095,0.15059,0,-0.1449,
78239      0.24113,-0.07441,0.44972,0,-0.02965,
78240      0,0,0,1,0
78241    ],
78242    Vintage: [
78243      0.62793,0.32021,-0.03965,0,0.03784,
78244      0.02578,0.64411,0.03259,0,0.02926,
78245      0.04660,-0.08512,0.52416,0,0.02023,
78246      0,0,0,1,0
78247    ],
78248    Kodachrome: [
78249      1.12855,-0.39673,-0.03992,0,0.24991,
78250      -0.16404,1.08352,-0.05498,0,0.09698,
78251      -0.16786,-0.56034,1.60148,0,0.13972,
78252      0,0,0,1,0
78253    ],
78254    Technicolor: [
78255      1.91252,-0.85453,-0.09155,0,0.04624,
78256      -0.30878,1.76589,-0.10601,0,-0.27589,
78257      -0.23110,-0.75018,1.84759,0,0.12137,
78258      0,0,0,1,0
78259    ],
78260    Polaroid: [
78261      1.438,-0.062,-0.062,0,0,
78262      -0.122,1.378,-0.122,0,0,
78263      -0.016,-0.016,1.483,0,0,
78264      0,0,0,1,0
78265    ],
78266    Sepia: [
78267      0.393, 0.769, 0.189, 0, 0,
78268      0.349, 0.686, 0.168, 0, 0,
78269      0.272, 0.534, 0.131, 0, 0,
78270      0, 0, 0, 1, 0
78271    ],
78272    BlackWhite: [
78273      1.5, 1.5, 1.5, 0, -1,
78274      1.5, 1.5, 1.5, 0, -1,
78275      1.5, 1.5, 1.5, 0, -1,
78276      0, 0, 0, 1, 0,
78277    ]
78278  };
78279
78280  for (var key in matrices) {
78281    filters[key] = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.Sepia.prototype */ {
78282
78283      /**
78284       * Filter type
78285       * @param {String} type
78286       * @default
78287       */
78288      type: key,
78289
78290      /**
78291       * Colormatrix for the effect
78292       * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning
78293       * outside the -1, 1 range.
78294       * @param {Array} matrix array of 20 numbers.
78295       * @default
78296       */
78297      matrix: matrices[key],
78298
78299      /**
78300       * Lock the matrix export for this kind of static, parameter less filters.
78301       */
78302      mainParameter: false,
78303      /**
78304       * Lock the colormatrix on the color part, skipping alpha
78305       */
78306      colorsOnly: true,
78307
78308    });
78309    fabric.Image.filters[key].fromObject = fabric.Image.filters.BaseFilter.fromObject;
78310  }
78311})( true ? exports : this);
78312
78313
78314(function(global) {
78315  'use strict';
78316
78317  var fabric = global.fabric,
78318      filters = fabric.Image.filters,
78319      createClass = fabric.util.createClass;
78320
78321  /**
78322   * Color Blend filter class
78323   * @class fabric.Image.filter.BlendColor
78324   * @memberOf fabric.Image.filters
78325   * @extends fabric.Image.filters.BaseFilter
78326   * @example
78327   * var filter = new fabric.Image.filters.BlendColor({
78328   *  color: '#000',
78329   *  mode: 'multiply'
78330   * });
78331   *
78332   * var filter = new fabric.Image.filters.BlendImage({
78333   *  image: fabricImageObject,
78334   *  mode: 'multiply',
78335   *  alpha: 0.5
78336   * });
78337   * object.filters.push(filter);
78338   * object.applyFilters();
78339   * canvas.renderAll();
78340   */
78341
78342  filters.BlendColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blend.prototype */ {
78343    type: 'BlendColor',
78344
78345    /**
78346     * Color to make the blend operation with. default to a reddish color since black or white
78347     * gives always strong result.
78348     **/
78349    color: '#F95C63',
78350
78351    /**
78352     * Blend mode for the filter: one of multiply, add, diff, screen, subtract,
78353     * darken, lighten, overlay, exclusion, tint.
78354     **/
78355    mode: 'multiply',
78356
78357    /**
78358     * alpha value. represent the strength of the blend color operation.
78359     **/
78360    alpha: 1,
78361
78362    /**
78363     * Fragment source for the Multiply program
78364     */
78365    fragmentSource: {
78366      multiply: 'gl_FragColor.rgb *= uColor.rgb;\n',
78367      screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n',
78368      add: 'gl_FragColor.rgb += uColor.rgb;\n',
78369      diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n',
78370      subtract: 'gl_FragColor.rgb -= uColor.rgb;\n',
78371      lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n',
78372      darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n',
78373      exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n',
78374      overlay: 'if (uColor.r < 0.5) {\n' +
78375          'gl_FragColor.r *= 2.0 * uColor.r;\n' +
78376        '} else {\n' +
78377          'gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n' +
78378        '}\n' +
78379        'if (uColor.g < 0.5) {\n' +
78380          'gl_FragColor.g *= 2.0 * uColor.g;\n' +
78381        '} else {\n' +
78382          'gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n' +
78383        '}\n' +
78384        'if (uColor.b < 0.5) {\n' +
78385          'gl_FragColor.b *= 2.0 * uColor.b;\n' +
78386        '} else {\n' +
78387          'gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n' +
78388        '}\n',
78389      tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\n' +
78390        'gl_FragColor.rgb += uColor.rgb;\n',
78391    },
78392
78393    /**
78394     * build the fragment source for the filters, joining the common part with
78395     * the specific one.
78396     * @param {String} mode the mode of the filter, a key of this.fragmentSource
78397     * @return {String} the source to be compiled
78398     * @private
78399     */
78400    buildSource: function(mode) {
78401      return 'precision highp float;\n' +
78402        'uniform sampler2D uTexture;\n' +
78403        'uniform vec4 uColor;\n' +
78404        'varying vec2 vTexCoord;\n' +
78405        'void main() {\n' +
78406          'vec4 color = texture2D(uTexture, vTexCoord);\n' +
78407          'gl_FragColor = color;\n' +
78408          'if (color.a > 0.0) {\n' +
78409            this.fragmentSource[mode] +
78410          '}\n' +
78411        '}';
78412    },
78413
78414    /**
78415     * Retrieves the cached shader.
78416     * @param {Object} options
78417     * @param {WebGLRenderingContext} options.context The GL context used for rendering.
78418     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
78419     */
78420    retrieveShader: function(options) {
78421      var cacheKey = this.type + '_' + this.mode, shaderSource;
78422      if (!options.programCache.hasOwnProperty(cacheKey)) {
78423        shaderSource = this.buildSource(this.mode);
78424        options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);
78425      }
78426      return options.programCache[cacheKey];
78427    },
78428
78429    /**
78430     * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.
78431     *
78432     * @param {Object} options
78433     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.
78434     */
78435    applyTo2d: function(options) {
78436      var imageData = options.imageData,
78437          data = imageData.data, iLen = data.length,
78438          tr, tg, tb,
78439          r, g, b,
78440          source, alpha1 = 1 - this.alpha;
78441
78442      source = new fabric.Color(this.color).getSource();
78443      tr = source[0] * this.alpha;
78444      tg = source[1] * this.alpha;
78445      tb = source[2] * this.alpha;
78446
78447      for (var i = 0; i < iLen; i += 4) {
78448
78449        r = data[i];
78450        g = data[i + 1];
78451        b = data[i + 2];
78452
78453        switch (this.mode) {
78454          case 'multiply':
78455            data[i] = r * tr / 255;
78456            data[i + 1] = g * tg / 255;
78457            data[i + 2] = b * tb / 255;
78458            break;
78459          case 'screen':
78460            data[i] = 255 - (255 - r) * (255 - tr) / 255;
78461            data[i + 1] = 255 - (255 - g) * (255 - tg) / 255;
78462            data[i + 2] = 255 - (255 - b) * (255 - tb) / 255;
78463            break;
78464          case 'add':
78465            data[i] = r + tr;
78466            data[i + 1] = g + tg;
78467            data[i + 2] = b + tb;
78468            break;
78469          case 'diff':
78470          case 'difference':
78471            data[i] = Math.abs(r - tr);
78472            data[i + 1] = Math.abs(g - tg);
78473            data[i + 2] = Math.abs(b - tb);
78474            break;
78475          case 'subtract':
78476            data[i] = r - tr;
78477            data[i + 1] = g - tg;
78478            data[i + 2] = b - tb;
78479            break;
78480          case 'darken':
78481            data[i] = Math.min(r, tr);
78482            data[i + 1] = Math.min(g, tg);
78483            data[i + 2] = Math.min(b, tb);
78484            break;
78485          case 'lighten':
78486            data[i] = Math.max(r, tr);
78487            data[i + 1] = Math.max(g, tg);
78488            data[i + 2] = Math.max(b, tb);
78489            break;
78490          case 'overlay':
78491            data[i] = tr < 128 ? (2 * r * tr / 255) : (255 - 2 * (255 - r) * (255 - tr) / 255);
78492            data[i + 1] = tg < 128 ? (2 * g * tg / 255) : (255 - 2 * (255 - g) * (255 - tg) / 255);
78493            data[i + 2] = tb < 128 ? (2 * b * tb / 255) : (255 - 2 * (255 - b) * (255 - tb) / 255);
78494            break;
78495          case 'exclusion':
78496            data[i] = tr + r - ((2 * tr * r) / 255);
78497            data[i + 1] = tg + g - ((2 * tg * g) / 255);
78498            data[i + 2] = tb + b - ((2 * tb * b) / 255);
78499            break;
78500          case 'tint':
78501            data[i] = tr + r * alpha1;
78502            data[i + 1] = tg + g * alpha1;
78503            data[i + 2] = tb + b * alpha1;
78504        }
78505      }
78506    },
78507
78508    /**
78509     * Return WebGL uniform locations for this filter's shader.
78510     *
78511     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
78512     * @param {WebGLShaderProgram} program This filter's compiled shader program.
78513     */
78514    getUniformLocations: function(gl, program) {
78515      return {
78516        uColor: gl.getUniformLocation(program, 'uColor'),
78517      };
78518    },
78519
78520    /**
78521     * Send data from this filter to its shader program's uniforms.
78522     *
78523     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
78524     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
78525     */
78526    sendUniformData: function(gl, uniformLocations) {
78527      var source = new fabric.Color(this.color).getSource();
78528      source[0] = this.alpha * source[0] / 255;
78529      source[1] = this.alpha * source[1] / 255;
78530      source[2] = this.alpha * source[2] / 255;
78531      source[3] = this.alpha;
78532      gl.uniform4fv(uniformLocations.uColor, source);
78533    },
78534
78535    /**
78536     * Returns object representation of an instance
78537     * @return {Object} Object representation of an instance
78538     */
78539    toObject: function() {
78540      return {
78541        type: this.type,
78542        color: this.color,
78543        mode: this.mode,
78544        alpha: this.alpha
78545      };
78546    }
78547  });
78548
78549  /**
78550   * Returns filter instance from an object representation
78551   * @static
78552   * @param {Object} object Object to create an instance from
78553   * @param {function} [callback] to be invoked after filter creation
78554   * @return {fabric.Image.filters.BlendColor} Instance of fabric.Image.filters.BlendColor
78555   */
78556  fabric.Image.filters.BlendColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;
78557
78558})( true ? exports : this
vendor: 8,175 bytes, lines 78558-78806
78558);
78559
78560
78561(function(global) {
78562  'use strict';
78563
78564  var fabric = global.fabric,
78565      filters = fabric.Image.filters,
78566      createClass = fabric.util.createClass;
78567
78568  /**
78569   * Image Blend filter class
78570   * @class fabric.Image.filter.BlendImage
78571   * @memberOf fabric.Image.filters
78572   * @extends fabric.Image.filters.BaseFilter
78573   * @example
78574   * var filter = new fabric.Image.filters.BlendColor({
78575   *  color: '#000',
78576   *  mode: 'multiply'
78577   * });
78578   *
78579   * var filter = new fabric.Image.filters.BlendImage({
78580   *  image: fabricImageObject,
78581   *  mode: 'multiply',
78582   *  alpha: 0.5
78583   * });
78584   * object.filters.push(filter);
78585   * object.applyFilters();
78586   * canvas.renderAll();
78587   */
78588
78589  filters.BlendImage = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.BlendImage.prototype */ {
78590    type: 'BlendImage',
78591
78592    /**
78593     * Color to make the blend operation with. default to a reddish color since black or white
78594     * gives always strong result.
78595     **/
78596    image: null,
78597
78598    /**
78599     * Blend mode for the filter: one of multiply, add, diff, screen, subtract,
78600     * darken, lighten, overlay, exclusion, tint.
78601     **/
78602    mode: 'multiply',
78603
78604    /**
78605     * alpha value. represent the strength of the blend image operation.
78606     * not implemented.
78607     **/
78608    alpha: 1,
78609
78610    vertexSource: 'attribute vec2 aPosition;\n' +
78611      'varying vec2 vTexCoord;\n' +
78612      'varying vec2 vTexCoord2;\n' +
78613      'uniform mat3 uTransformMatrix;\n' +
78614      'void main() {\n' +
78615        'vTexCoord = aPosition;\n' +
78616        'vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\n' +
78617        'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n' +
78618      '}',
78619
78620    /**
78621     * Fragment source for the Multiply program
78622     */
78623    fragmentSource: {
78624      multiply: 'precision highp float;\n' +
78625        'uniform sampler2D uTexture;\n' +
78626        'uniform sampler2D uImage;\n' +
78627        'uniform vec4 uColor;\n' +
78628        'varying vec2 vTexCoord;\n' +
78629        'varying vec2 vTexCoord2;\n' +
78630        'void main() {\n' +
78631          'vec4 color = texture2D(uTexture, vTexCoord);\n' +
78632          'vec4 color2 = texture2D(uImage, vTexCoord2);\n' +
78633          'color.rgba *= color2.rgba;\n' +
78634          'gl_FragColor = color;\n' +
78635        '}',
78636      mask: 'precision highp float;\n' +
78637        'uniform sampler2D uTexture;\n' +
78638        'uniform sampler2D uImage;\n' +
78639        'uniform vec4 uColor;\n' +
78640        'varying vec2 vTexCoord;\n' +
78641        'varying vec2 vTexCoord2;\n' +
78642        'void main() {\n' +
78643          'vec4 color = texture2D(uTexture, vTexCoord);\n' +
78644          'vec4 color2 = texture2D(uImage, vTexCoord2);\n' +
78645          'color.a = color2.a;\n' +
78646          'gl_FragColor = color;\n' +
78647        '}',
78648    },
78649
78650    /**
78651     * Retrieves the cached shader.
78652     * @param {Object} options
78653     * @param {WebGLRenderingContext} options.context The GL context used for rendering.
78654     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
78655     */
78656    retrieveShader: function(options) {
78657      var cacheKey = this.type + '_' + this.mode;
78658      var shaderSource = this.fragmentSource[this.mode];
78659      if (!options.programCache.hasOwnProperty(cacheKey)) {
78660        options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);
78661      }
78662      return options.programCache[cacheKey];
78663    },
78664
78665    applyToWebGL: function(options) {
78666      // load texture to blend.
78667      var gl = options.context,
78668          texture = this.createTexture(options.filterBackend, this.image);
78669      this.bindAdditionalTexture(gl, texture, gl.TEXTURE1);
78670      this.callSuper('applyToWebGL', options);
78671      this.unbindAdditionalTexture(gl, gl.TEXTURE1);
78672    },
78673
78674    createTexture: function(backend, image) {
78675      return backend.getCachedTexture(image.cacheKey, image._element);
78676    },
78677
78678    /**
78679     * Calculate a transformMatrix to adapt the image to blend over
78680     * @param {Object} options
78681     * @param {WebGLRenderingContext} options.context The GL context used for rendering.
78682     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
78683     */
78684    calculateMatrix: function() {
78685      var image = this.image,
78686          width = image._element.width,
78687          height = image._element.height;
78688      return [
78689        1 / image.scaleX, 0, 0,
78690        0, 1 / image.scaleY, 0,
78691        -image.left / width, -image.top / height, 1
78692      ];
78693    },
78694
78695    /**
78696     * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.
78697     *
78698     * @param {Object} options
78699     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.
78700     */
78701    applyTo2d: function(options) {
78702      var imageData = options.imageData,
78703          resources = options.filterBackend.resources,
78704          data = imageData.data, iLen = data.length,
78705          width = imageData.width,
78706          height = imageData.height,
78707          tr, tg, tb, ta,
78708          r, g, b, a,
78709          canvas1, context, image = this.image, blendData;
78710
78711      if (!resources.blendImage) {
78712        resources.blendImage = fabric.util.createCanvasElement();
78713      }
78714      canvas1 = resources.blendImage;
78715      context = canvas1.getContext('2d');
78716      if (canvas1.width !== width || canvas1.height !== height) {
78717        canvas1.width = width;
78718        canvas1.height = height;
78719      }
78720      else {
78721        context.clearRect(0, 0, width, height);
78722      }
78723      context.setTransform(image.scaleX, 0, 0, image.scaleY, image.left, image.top);
78724      context.drawImage(image._element, 0, 0, width, height);
78725      blendData = context.getImageData(0, 0, width, height).data;
78726      for (var i = 0; i < iLen; i += 4) {
78727
78728        r = data[i];
78729        g = data[i + 1];
78730        b = data[i + 2];
78731        a = data[i + 3];
78732
78733        tr = blendData[i];
78734        tg = blendData[i + 1];
78735        tb = blendData[i + 2];
78736        ta = blendData[i + 3];
78737
78738        switch (this.mode) {
78739          case 'multiply':
78740            data[i] = r * tr / 255;
78741            data[i + 1] = g * tg / 255;
78742            data[i + 2] = b * tb / 255;
78743            data[i + 3] = a * ta / 255;
78744            break;
78745          case 'mask':
78746            data[i + 3] = ta;
78747            break;
78748        }
78749      }
78750    },
78751
78752    /**
78753     * Return WebGL uniform locations for this filter's shader.
78754     *
78755     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
78756     * @param {WebGLShaderProgram} program This filter's compiled shader program.
78757     */
78758    getUniformLocations: function(gl, program) {
78759      return {
78760        uTransformMatrix: gl.getUniformLocation(program, 'uTransformMatrix'),
78761        uImage: gl.getUniformLocation(program, 'uImage'),
78762      };
78763    },
78764
78765    /**
78766     * Send data from this filter to its shader program's uniforms.
78767     *
78768     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
78769     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
78770     */
78771    sendUniformData: function(gl, uniformLocations) {
78772      var matrix = this.calculateMatrix();
78773      gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.
78774      gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix);
78775    },
78776
78777    /**
78778     * Returns object representation of an instance
78779     * @return {Object} Object representation of an instance
78780     */
78781    toObject: function() {
78782      return {
78783        type: this.type,
78784        image: this.image && this.image.toObject(),
78785        mode: this.mode,
78786        alpha: this.alpha
78787      };
78788    }
78789  });
78790
78791  /**
78792   * Returns filter instance from an object representation
78793   * @static
78794   * @param {Object} object Object to create an instance from
78795   * @param {function} callback to be invoked after filter creation
78796   * @return {fabric.Image.filters.BlendImage} Instance of fabric.Image.filters.BlendImage
78797   */
78798  fabric.Image.filters.BlendImage.fromObject = function(object, callback) {
78799    fabric.Image.fromObject(object.image, function(image) {
78800      var options = fabric.util.object.clone(object);
78801      options.image = image;
78802      callback(new fabric.Image.filters.BlendImage(options));
78803    });
78804  };
78805
78806})( true ? exports : 
78806this
vendor: 16,923 bytes, lines 78806-79298
78806);
78807
78808
78809(function(global) {
78810
78811  'use strict';
78812
78813  var fabric  = global.fabric || (global.fabric = { }), pow = Math.pow, floor = Math.floor,
78814      sqrt = Math.sqrt, abs = Math.abs, round = Math.round, sin = Math.sin,
78815      ceil = Math.ceil,
78816      filters = fabric.Image.filters,
78817      createClass = fabric.util.createClass;
78818
78819  /**
78820   * Resize image filter class
78821   * @class fabric.Image.filters.Resize
78822   * @memberOf fabric.Image.filters
78823   * @extends fabric.Image.filters.BaseFilter
78824   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
78825   * @example
78826   * var filter = new fabric.Image.filters.Resize();
78827   * object.filters.push(filter);
78828   * object.applyFilters(canvas.renderAll.bind(canvas));
78829   */
78830  filters.Resize = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ {
78831
78832    /**
78833     * Filter type
78834     * @param {String} type
78835     * @default
78836     */
78837    type: 'Resize',
78838
78839    /**
78840     * Resize type
78841     * for webgl resizeType is just lanczos, for canvas2d can be:
78842     * bilinear, hermite, sliceHack, lanczos.
78843     * @param {String} resizeType
78844     * @default
78845     */
78846    resizeType: 'hermite',
78847
78848    /**
78849     * Scale factor for resizing, x axis
78850     * @param {Number} scaleX
78851     * @default
78852     */
78853    scaleX: 1,
78854
78855    /**
78856     * Scale factor for resizing, y axis
78857     * @param {Number} scaleY
78858     * @default
78859     */
78860    scaleY: 1,
78861
78862    /**
78863     * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos
78864     * @param {Number} lanczosLobes
78865     * @default
78866     */
78867    lanczosLobes: 3,
78868
78869
78870    /**
78871     * Return WebGL uniform locations for this filter's shader.
78872     *
78873     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
78874     * @param {WebGLShaderProgram} program This filter's compiled shader program.
78875     */
78876    getUniformLocations: function(gl, program) {
78877      return {
78878        uDelta: gl.getUniformLocation(program, 'uDelta'),
78879        uTaps: gl.getUniformLocation(program, 'uTaps'),
78880      };
78881    },
78882
78883    /**
78884     * Send data from this filter to its shader program's uniforms.
78885     *
78886     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
78887     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
78888     */
78889    sendUniformData: function(gl, uniformLocations) {
78890      gl.uniform2fv(uniformLocations.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]);
78891      gl.uniform1fv(uniformLocations.uTaps, this.taps);
78892    },
78893
78894    /**
78895     * Retrieves the cached shader.
78896     * @param {Object} options
78897     * @param {WebGLRenderingContext} options.context The GL context used for rendering.
78898     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
78899     */
78900    retrieveShader: function(options) {
78901      var filterWindow = this.getFilterWindow(), cacheKey = this.type + '_' + filterWindow;
78902      if (!options.programCache.hasOwnProperty(cacheKey)) {
78903        var fragmentShader = this.generateShader(filterWindow);
78904        options.programCache[cacheKey] = this.createProgram(options.context, fragmentShader);
78905      }
78906      return options.programCache[cacheKey];
78907    },
78908
78909    getFilterWindow: function() {
78910      var scale = this.tempScale;
78911      return Math.ceil(this.lanczosLobes / scale);
78912    },
78913
78914    getTaps: function() {
78915      var lobeFunction = this.lanczosCreate(this.lanczosLobes), scale = this.tempScale,
78916          filterWindow = this.getFilterWindow(), taps = new Array(filterWindow);
78917      for (var i = 1; i <= filterWindow; i++) {
78918        taps[i - 1] = lobeFunction(i * scale);
78919      }
78920      return taps;
78921    },
78922
78923    /**
78924     * Generate vertex and shader sources from the necessary steps numbers
78925     * @param {Number} filterWindow
78926     */
78927    generateShader: function(filterWindow) {
78928      var offsets = new Array(filterWindow),
78929          fragmentShader = this.fragmentSourceTOP, filterWindow;
78930
78931      for (var i = 1; i <= filterWindow; i++) {
78932        offsets[i - 1] = i + '.0 * uDelta';
78933      }
78934
78935      fragmentShader += 'uniform float uTaps[' + filterWindow + '];\n';
78936      fragmentShader += 'void main() {\n';
78937      fragmentShader += '  vec4 color = texture2D(uTexture, vTexCoord);\n';
78938      fragmentShader += '  float sum = 1.0;\n';
78939
78940      offsets.forEach(function(offset, i) {
78941        fragmentShader += '  color += texture2D(uTexture, vTexCoord + ' + offset + ') * uTaps[' + i + '];\n';
78942        fragmentShader += '  color += texture2D(uTexture, vTexCoord - ' + offset + ') * uTaps[' + i + '];\n';
78943        fragmentShader += '  sum += 2.0 * uTaps[' + i + '];\n';
78944      });
78945      fragmentShader += '  gl_FragColor = color / sum;\n';
78946      fragmentShader += '}';
78947      return fragmentShader;
78948    },
78949
78950    fragmentSourceTOP: 'precision highp float;\n' +
78951      'uniform sampler2D uTexture;\n' +
78952      'uniform vec2 uDelta;\n' +
78953      'varying vec2 vTexCoord;\n',
78954
78955    /**
78956     * Apply the resize filter to the image
78957     * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.
78958     *
78959     * @param {Object} options
78960     * @param {Number} options.passes The number of filters remaining to be executed
78961     * @param {Boolean} options.webgl Whether to use webgl to render the filter.
78962     * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.
78963     * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.
78964     * @param {WebGLRenderingContext} options.context The GL context used for rendering.
78965     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
78966     */
78967    applyTo: function(options) {
78968      if (options.webgl) {
78969        options.passes++;
78970        this.width = options.sourceWidth;
78971        this.horizontal = true;
78972        this.dW = Math.round(this.width * this.scaleX);
78973        this.dH = options.sourceHeight;
78974        this.tempScale = this.dW / this.width;
78975        this.taps = this.getTaps();
78976        options.destinationWidth = this.dW;
78977        this._setupFrameBuffer(options);
78978        this.applyToWebGL(options);
78979        this._swapTextures(options);
78980        options.sourceWidth = options.destinationWidth;
78981
78982        this.height = options.sourceHeight;
78983        this.horizontal = false;
78984        this.dH = Math.round(this.height * this.scaleY);
78985        this.tempScale = this.dH / this.height;
78986        this.taps = this.getTaps();
78987        options.destinationHeight = this.dH;
78988        this._setupFrameBuffer(options);
78989        this.applyToWebGL(options);
78990        this._swapTextures(options);
78991        options.sourceHeight = options.destinationHeight;
78992      }
78993      else {
78994        this.applyTo2d(options);
78995      }
78996    },
78997
78998    isNeutralState: function() {
78999      return this.scaleX === 1 && this.scaleY === 1;
79000    },
79001
79002    lanczosCreate: function(lobes) {
79003      return function(x) {
79004        if (x >= lobes || x <= -lobes) {
79005          return 0.0;
79006        }
79007        if (x < 1.19209290E-07 && x > -1.19209290E-07) {
79008          return 1.0;
79009        }
79010        x *= Math.PI;
79011        var xx = x / lobes;
79012        return (sin(x) / x) * sin(xx) / xx;
79013      };
79014    },
79015
79016    /**
79017     * Applies filter to canvas element
79018     * @memberOf fabric.Image.filters.Resize.prototype
79019     * @param {Object} canvasEl Canvas element to apply filter to
79020     * @param {Number} scaleX
79021     * @param {Number} scaleY
79022     */
79023    applyTo2d: function(options) {
79024      var imageData = options.imageData,
79025          scaleX = this.scaleX,
79026          scaleY = this.scaleY;
79027
79028      this.rcpScaleX = 1 / scaleX;
79029      this.rcpScaleY = 1 / scaleY;
79030
79031      var oW = imageData.width, oH = imageData.height,
79032          dW = round(oW * scaleX), dH = round(oH * scaleY),
79033          newData;
79034
79035      if (this.resizeType === 'sliceHack') {
79036        newData = this.sliceByTwo(options, oW, oH, dW, dH);
79037      }
79038      else if (this.resizeType === 'hermite') {
79039        newData = this.hermiteFastResize(options, oW, oH, dW, dH);
79040      }
79041      else if (this.resizeType === 'bilinear') {
79042        newData = this.bilinearFiltering(options, oW, oH, dW, dH);
79043      }
79044      else if (this.resizeType === 'lanczos') {
79045        newData = this.lanczosResize(options, oW, oH, dW, dH);
79046      }
79047      options.imageData = newData;
79048    },
79049
79050    /**
79051     * Filter sliceByTwo
79052     * @param {Object} canvasEl Canvas element to apply filter to
79053     * @param {Number} oW Original Width
79054     * @param {Number} oH Original Height
79055     * @param {Number} dW Destination Width
79056     * @param {Number} dH Destination Height
79057     * @returns {ImageData}
79058     */
79059    sliceByTwo: function(options, oW, oH, dW, dH) {
79060      var imageData = options.imageData,
79061          mult = 0.5, doneW = false, doneH = false, stepW = oW * mult,
79062          stepH = oH * mult, resources = fabric.filterBackend.resources,
79063          tmpCanvas, ctx, sX = 0, sY = 0, dX = oW, dY = 0;
79064      if (!resources.sliceByTwo) {
79065        resources.sliceByTwo = document.createElement('canvas');
79066      }
79067      tmpCanvas = resources.sliceByTwo;
79068      if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) {
79069        tmpCanvas.width = oW * 1.5;
79070        tmpCanvas.height = oH;
79071      }
79072      ctx = tmpCanvas.getContext('2d');
79073      ctx.clearRect(0, 0, oW * 1.5, oH);
79074      ctx.putImageData(imageData, 0, 0);
79075
79076      dW = floor(dW);
79077      dH = floor(dH);
79078
79079      while (!doneW || !doneH) {
79080        oW = stepW;
79081        oH = stepH;
79082        if (dW < floor(stepW * mult)) {
79083          stepW = floor(stepW * mult);
79084        }
79085        else {
79086          stepW = dW;
79087          doneW = true;
79088        }
79089        if (dH < floor(stepH * mult)) {
79090          stepH = floor(stepH * mult);
79091        }
79092        else {
79093          stepH = dH;
79094          doneH = true;
79095        }
79096        ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH);
79097        sX = dX;
79098        sY = dY;
79099        dY += stepH;
79100      }
79101      return ctx.getImageData(sX, sY, dW, dH);
79102    },
79103
79104    /**
79105     * Filter lanczosResize
79106     * @param {Object} canvasEl Canvas element to apply filter to
79107     * @param {Number} oW Original Width
79108     * @param {Number} oH Original Height
79109     * @param {Number} dW Destination Width
79110     * @param {Number} dH Destination Height
79111     * @returns {ImageData}
79112     */
79113    lanczosResize: function(options, oW, oH, dW, dH) {
79114
79115      function process(u) {
79116        var v, i, weight, idx, a, red, green,
79117            blue, alpha, fX, fY;
79118        center.x = (u + 0.5) * ratioX;
79119        icenter.x = floor(center.x);
79120        for (v = 0; v < dH; v++) {
79121          center.y = (v + 0.5) * ratioY;
79122          icenter.y = floor(center.y);
79123          a = 0; red = 0; green = 0; blue = 0; alpha = 0;
79124          for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {
79125            if (i < 0 || i >= oW) {
79126              continue;
79127            }
79128            fX = floor(1000 * abs(i - center.x));
79129            if (!cacheLanc[fX]) {
79130              cacheLanc[fX] = { };
79131            }
79132            for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {
79133              if (j < 0 || j >= oH) {
79134                continue;
79135              }
79136              fY = floor(1000 * abs(j - center.y));
79137              if (!cacheLanc[fX][fY]) {
79138                cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000);
79139              }
79140              weight = cacheLanc[fX][fY];
79141              if (weight > 0) {
79142                idx = (j * oW + i) * 4;
79143                a += weight;
79144                red += weight * srcData[idx];
79145                green += weight * srcData[idx + 1];
79146                blue += weight * srcData[idx + 2];
79147                alpha += weight * srcData[idx + 3];
79148              }
79149            }
79150          }
79151          idx = (v * dW + u) * 4;
79152          destData[idx] = red / a;
79153          destData[idx + 1] = green / a;
79154          destData[idx + 2] = blue / a;
79155          destData[idx + 3] = alpha / a;
79156        }
79157
79158        if (++u < dW) {
79159          return process(u);
79160        }
79161        else {
79162          return destImg;
79163        }
79164      }
79165
79166      var srcData = options.imageData.data,
79167          destImg = options.ctx.createImageData(dW, dH),
79168          destData = destImg.data,
79169          lanczos = this.lanczosCreate(this.lanczosLobes),
79170          ratioX = this.rcpScaleX, ratioY = this.rcpScaleY,
79171          rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY,
79172          range2X = ceil(ratioX * this.lanczosLobes / 2),
79173          range2Y = ceil(ratioY * this.lanczosLobes / 2),
79174          cacheLanc = { }, center = { }, icenter = { };
79175
79176      return process(0);
79177    },
79178
79179    /**
79180     * bilinearFiltering
79181     * @param {Object} canvasEl Canvas element to apply filter to
79182     * @param {Number} oW Original Width
79183     * @param {Number} oH Original Height
79184     * @param {Number} dW Destination Width
79185     * @param {Number} dH Destination Height
79186     * @returns {ImageData}
79187     */
79188    bilinearFiltering: function(options, oW, oH, dW, dH) {
79189      var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl,
79190          color, offset = 0, origPix, ratioX = this.rcpScaleX,
79191          ratioY = this.rcpScaleY,
79192          w4 = 4 * (oW - 1), img = options.imageData,
79193          pixels = img.data, destImage = options.ctx.createImageData(dW, dH),
79194          destPixels = destImage.data;
79195      for (i = 0; i < dH; i++) {
79196        for (j = 0; j < dW; j++) {
79197          x = floor(ratioX * j);
79198          y = floor(ratioY * i);
79199          xDiff = ratioX * j - x;
79200          yDiff = ratioY * i - y;
79201          origPix = 4 * (y * oW + x);
79202
79203          for (chnl = 0; chnl < 4; chnl++) {
79204            a = pixels[origPix + chnl];
79205            b = pixels[origPix + 4 + chnl];
79206            c = pixels[origPix + w4 + chnl];
79207            d = pixels[origPix + w4 + 4 + chnl];
79208            color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) +
79209                    c * yDiff * (1 - xDiff) + d * xDiff * yDiff;
79210            destPixels[offset++] = color;
79211          }
79212        }
79213      }
79214      return destImage;
79215    },
79216
79217    /**
79218     * hermiteFastResize
79219     * @param {Object} canvasEl Canvas element to apply filter to
79220     * @param {Number} oW Original Width
79221     * @param {Number} oH Original Height
79222     * @param {Number} dW Destination Width
79223     * @param {Number} dH Destination Height
79224     * @returns {ImageData}
79225     */
79226    hermiteFastResize: function(options, oW, oH, dW, dH) {
79227      var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY,
79228          ratioWHalf = ceil(ratioW / 2),
79229          ratioHHalf = ceil(ratioH / 2),
79230          img = options.imageData, data = img.data,
79231          img2 = options.ctx.createImageData(dW, dH), data2 = img2.data;
79232      for (var j = 0; j < dH; j++) {
79233        for (var i = 0; i < dW; i++) {
79234          var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0,
79235              gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + 0.5) * ratioH;
79236          for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {
79237            var dy = abs(centerY - (yy + 0.5)) / ratioHHalf,
79238                centerX = (i + 0.5) * ratioW, w0 = dy * dy;
79239            for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {
79240              var dx = abs(centerX - (xx + 0.5)) / ratioWHalf,
79241                  w = sqrt(w0 + dx * dx);
79242              /* eslint-disable max-depth */
79243              if (w > 1 && w < -1) {
79244                continue;
79245              }
79246              //hermite filter
79247              weight = 2 * w * w * w - 3 * w * w + 1;
79248              if (weight > 0) {
79249                dx = 4 * (xx + yy * oW);
79250                //alpha
79251                gxA += weight * data[dx + 3];
79252                weightsAlpha += weight;
79253                //colors
79254                if (data[dx + 3] < 255) {
79255                  weight = weight * data[dx + 3] / 250;
79256                }
79257                gxR += weight * data[dx];
79258                gxG += weight * data[dx + 1];
79259                gxB += weight * data[dx + 2];
79260                weights += weight;
79261              }
79262              /* eslint-enable max-depth */
79263            }
79264          }
79265          data2[x2] = gxR / weights;
79266          data2[x2 + 1] = gxG / weights;
79267          data2[x2 + 2] = gxB / weights;
79268          data2[x2 + 3] = gxA / weightsAlpha;
79269        }
79270      }
79271      return img2;
79272    },
79273
79274    /**
79275     * Returns object representation of an instance
79276     * @return {Object} Object representation of an instance
79277     */
79278    toObject: function() {
79279      return {
79280        type: this.type,
79281        scaleX: this.scaleX,
79282        scaleY: this.scaleY,
79283        resizeType: this.resizeType,
79284        lanczosLobes: this.lanczosLobes
79285      };
79286    }
79287  });
79288
79289  /**
79290   * Returns filter instance from an object representation
79291   * @static
79292   * @param {Object} object Object to create an instance from
79293   * @param {Function} [callback] to be invoked after filter creation
79294   * @return {fabric.Image.filters.Resize} Instance of fabric.Image.filters.Resize
79295   */
79296  fabric.Image.filters.Resize.fromObject = fabric.Image.filters.BaseFilter.fromObject;
79297
79298})( true ? exports : 
79298this);
79299
79300
79301(function(global) {
79302
79303  'use strict';
79304
79305  var fabric  = global.fabric || (global.fabric = { }),
79306      filters = fabric.Image.filters,
79307      createClass = fabric.util.createClass;
79308
79309  /**
79310   * Contrast filter class
79311   * @class fabric.Image.filters.Contrast
79312   * @memberOf fabric.Image.filters
79313   * @extends fabric.Image.filters.BaseFilter
79314   * @see {@link fabric.Image.filters.Contrast#initialize}
vendor: 11,698 bytes, lines 79314-79658
79314 for constructor definition
79315   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
79316   * @example
79317   * var filter = new fabric.Image.filters.Contrast({
79318   *   contrast: 0.25
79319   * });
79320   * object.filters.push(filter);
79321   * object.applyFilters();
79322   */
79323  filters.Contrast = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Contrast.prototype */ {
79324
79325    /**
79326     * Filter type
79327     * @param {String} type
79328     * @default
79329     */
79330    type: 'Contrast',
79331
79332    fragmentSource: 'precision highp float;\n' +
79333      'uniform sampler2D uTexture;\n' +
79334      'uniform float uContrast;\n' +
79335      'varying vec2 vTexCoord;\n' +
79336      'void main() {\n' +
79337        'vec4 color = texture2D(uTexture, vTexCoord);\n' +
79338        'float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\n' +
79339        'color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\n' +
79340        'gl_FragColor = color;\n' +
79341      '}',
79342
79343    /**
79344     * contrast value, range from -1 to 1.
79345     * @param {Number} contrast
79346     * @default 0
79347     */
79348    contrast: 0,
79349
79350    mainParameter: 'contrast',
79351
79352    /**
79353     * Constructor
79354     * @memberOf fabric.Image.filters.Contrast.prototype
79355     * @param {Object} [options] Options object
79356     * @param {Number} [options.contrast=0] Value to contrast the image up (-1...1)
79357     */
79358
79359    /**
79360      * Apply the Contrast operation to a Uint8Array representing the pixels of an image.
79361      *
79362      * @param {Object} options
79363      * @param {ImageData} options.imageData The Uint8Array to be filtered.
79364      */
79365    applyTo2d: function(options) {
79366      if (this.contrast === 0) {
79367        return;
79368      }
79369      var imageData = options.imageData, i, len,
79370          data = imageData.data, len = data.length,
79371          contrast = Math.floor(this.contrast * 255),
79372          contrastF = 259 * (contrast + 255) / (255 * (259 - contrast));
79373
79374      for (i = 0; i < len; i += 4) {
79375        data[i] = contrastF * (data[i] - 128) + 128;
79376        data[i + 1] = contrastF * (data[i + 1] - 128) + 128;
79377        data[i + 2] = contrastF * (data[i + 2] - 128) + 128;
79378      }
79379    },
79380
79381    /**
79382     * Return WebGL uniform locations for this filter's shader.
79383     *
79384     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
79385     * @param {WebGLShaderProgram} program This filter's compiled shader program.
79386     */
79387    getUniformLocations: function(gl, program) {
79388      return {
79389        uContrast: gl.getUniformLocation(program, 'uContrast'),
79390      };
79391    },
79392
79393    /**
79394     * Send data from this filter to its shader program's uniforms.
79395     *
79396     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
79397     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
79398     */
79399    sendUniformData: function(gl, uniformLocations) {
79400      gl.uniform1f(uniformLocations.uContrast, this.contrast);
79401    },
79402  });
79403
79404  /**
79405   * Returns filter instance from an object representation
79406   * @static
79407   * @param {Object} object Object to create an instance from
79408   * @param {function} [callback] to be invoked after filter creation
79409   * @return {fabric.Image.filters.Contrast} Instance of fabric.Image.filters.Contrast
79410   */
79411  fabric.Image.filters.Contrast.fromObject = fabric.Image.filters.BaseFilter.fromObject;
79412
79413})( true ? exports : this);
79414
79415
79416(function(global) {
79417
79418  'use strict';
79419
79420  var fabric  = global.fabric || (global.fabric = { }),
79421      filters = fabric.Image.filters,
79422      createClass = fabric.util.createClass;
79423
79424  /**
79425   * Saturate filter class
79426   * @class fabric.Image.filters.Saturation
79427   * @memberOf fabric.Image.filters
79428   * @extends fabric.Image.filters.BaseFilter
79429   * @see {@link fabric.Image.filters.Saturation#initialize} for constructor definition
79430   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
79431   * @example
79432   * var filter = new fabric.Image.filters.Saturation({
79433   *   saturation: 1
79434   * });
79435   * object.filters.push(filter);
79436   * object.applyFilters();
79437   */
79438  filters.Saturation = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Saturation.prototype */ {
79439
79440    /**
79441     * Filter type
79442     * @param {String} type
79443     * @default
79444     */
79445    type: 'Saturation',
79446
79447    fragmentSource: 'precision highp float;\n' +
79448      'uniform sampler2D uTexture;\n' +
79449      'uniform float uSaturation;\n' +
79450      'varying vec2 vTexCoord;\n' +
79451      'void main() {\n' +
79452        'vec4 color = texture2D(uTexture, vTexCoord);\n' +
79453        'float rgMax = max(color.r, color.g);\n' +
79454        'float rgbMax = max(rgMax, color.b);\n' +
79455        'color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\n' +
79456        'color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\n' +
79457        'color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\n' +
79458        'gl_FragColor = color;\n' +
79459      '}',
79460
79461    /**
79462     * Saturation value, from -1 to 1.
79463     * Increases/decreases the color saturation.
79464     * A value of 0 has no effect.
79465     *
79466     * @param {Number} saturation
79467     * @default
79468     */
79469    saturation: 0,
79470
79471    mainParameter: 'saturation',
79472
79473    /**
79474     * Constructor
79475     * @memberOf fabric.Image.filters.Saturate.prototype
79476     * @param {Object} [options] Options object
79477     * @param {Number} [options.saturate=0] Value to saturate the image (-1...1)
79478     */
79479
79480    /**
79481     * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image.
79482     *
79483     * @param {Object} options
79484     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.
79485     */
79486    applyTo2d: function(options) {
79487      if (this.saturation === 0) {
79488        return;
79489      }
79490      var imageData = options.imageData,
79491          data = imageData.data, len = data.length,
79492          adjust = -this.saturation, i, max;
79493
79494      for (i = 0; i < len; i += 4) {
79495        max = Math.max(data[i], data[i + 1], data[i + 2]);
79496        data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;
79497        data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;
79498        data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;
79499      }
79500    },
79501
79502    /**
79503     * Return WebGL uniform locations for this filter's shader.
79504     *
79505     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
79506     * @param {WebGLShaderProgram} program This filter's compiled shader program.
79507     */
79508    getUniformLocations: function(gl, program) {
79509      return {
79510        uSaturation: gl.getUniformLocation(program, 'uSaturation'),
79511      };
79512    },
79513
79514    /**
79515     * Send data from this filter to its shader program's uniforms.
79516     *
79517     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
79518     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
79519     */
79520    sendUniformData: function(gl, uniformLocations) {
79521      gl.uniform1f(uniformLocations.uSaturation, -this.saturation);
79522    },
79523  });
79524
79525  /**
79526   * Returns filter instance from an object representation
79527   * @static
79528   * @param {Object} object Object to create an instance from
79529   * @param {Function} [callback] to be invoked after filter creation
79530   * @return {fabric.Image.filters.Saturation} Instance of fabric.Image.filters.Saturate
79531   */
79532  fabric.Image.filters.Saturation.fromObject = fabric.Image.filters.BaseFilter.fromObject;
79533
79534})( true ? exports : this);
79535
79536
79537(function(global) {
79538
79539  'use strict';
79540
79541  var fabric  = global.fabric || (global.fabric = { }),
79542      filters = fabric.Image.filters,
79543      createClass = fabric.util.createClass;
79544
79545  /**
79546   * Vibrance filter class
79547   * @class fabric.Image.filters.Vibrance
79548   * @memberOf fabric.Image.filters
79549   * @extends fabric.Image.filters.BaseFilter
79550   * @see {@link fabric.Image.filters.Vibrance#initialize} for constructor definition
79551   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
79552   * @example
79553   * var filter = new fabric.Image.filters.Vibrance({
79554   *   vibrance: 1
79555   * });
79556   * object.filters.push(filter);
79557   * object.applyFilters();
79558   */
79559  filters.Vibrance = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Vibrance.prototype */ {
79560
79561    /**
79562     * Filter type
79563     * @param {String} type
79564     * @default
79565     */
79566    type: 'Vibrance',
79567
79568    fragmentSource: 'precision highp float;\n' +
79569      'uniform sampler2D uTexture;\n' +
79570      'uniform float uVibrance;\n' +
79571      'varying vec2 vTexCoord;\n' +
79572      'void main() {\n' +
79573        'vec4 color = texture2D(uTexture, vTexCoord);\n' +
79574        'float max = max(color.r, max(color.g, color.b));\n' +
79575        'float avg = (color.r + color.g + color.b) / 3.0;\n' +
79576        'float amt = (abs(max - avg) * 2.0) * uVibrance;\n' +
79577        'color.r += max != color.r ? (max - color.r) * amt : 0.00;\n' +
79578        'color.g += max != color.g ? (max - color.g) * amt : 0.00;\n' +
79579        'color.b += max != color.b ? (max - color.b) * amt : 0.00;\n' +
79580        'gl_FragColor = color;\n' +
79581      '}',
79582
79583    /**
79584     * Vibrance value, from -1 to 1.
79585     * Increases/decreases the saturation of more muted colors with less effect on saturated colors.
79586     * A value of 0 has no effect.
79587     *
79588     * @param {Number} vibrance
79589     * @default
79590     */
79591    vibrance: 0,
79592
79593    mainParameter: 'vibrance',
79594
79595    /**
79596     * Constructor
79597     * @memberOf fabric.Image.filters.Vibrance.prototype
79598     * @param {Object} [options] Options object
79599     * @param {Number} [options.vibrance=0] Vibrance value for the image (between -1 and 1)
79600     */
79601
79602    /**
79603     * Apply the Vibrance operation to a Uint8ClampedArray representing the pixels of an image.
79604     *
79605     * @param {Object} options
79606     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.
79607     */
79608    applyTo2d: function(options) {
79609      if (this.vibrance === 0) {
79610        return;
79611      }
79612      var imageData = options.imageData,
79613          data = imageData.data, len = data.length,
79614          adjust = -this.vibrance, i, max, avg, amt;
79615
79616      for (i = 0; i < len; i += 4) {
79617        max = Math.max(data[i], data[i + 1], data[i + 2]);
79618        avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
79619        amt = ((Math.abs(max - avg) * 2 / 255) * adjust);
79620        data[i] += max !== data[i] ? (max - data[i]) * amt : 0;
79621        data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * amt : 0;
79622        data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * amt : 0;
79623      }
79624    },
79625
79626    /**
79627     * Return WebGL uniform locations for this filter's shader.
79628     *
79629     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
79630     * @param {WebGLShaderProgram} program This filter's compiled shader program.
79631     */
79632    getUniformLocations: function(gl, program) {
79633      return {
79634        uVibrance: gl.getUniformLocation(program, 'uVibrance'),
79635      };
79636    },
79637
79638    /**
79639     * Send data from this filter to its shader program's uniforms.
79640     *
79641     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
79642     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
79643     */
79644    sendUniformData: function(gl, uniformLocations) {
79645      gl.uniform1f(uniformLocations.uVibrance, -this.vibrance);
79646    },
79647  });
79648
79649  /**
79650   * Returns filter instance from an object representation
79651   * @static
79652   * @param {Object} object Object to create an instance from
79653   * @param {Function} [callback] to be invoked after filter creation
79654   * @return {fabric.Image.filters.Vibrance} Instance of fabric.Image.filters.Vibrance
79655   */
79656  fabric.Image.filters.Vibrance.fromObject = fabric.Image.filters.BaseFilter.fromObject;
79657
79658})( true ? exports : this
vendor: 7,872 bytes, lines 79658-79875
79658);
79659
79660
79661(function(global) {
79662
79663  'use strict';
79664
79665  var fabric  = global.fabric || (global.fabric = { }),
79666      filters = fabric.Image.filters,
79667      createClass = fabric.util.createClass;
79668
79669  /**
79670   * Blur filter class
79671   * @class fabric.Image.filters.Blur
79672   * @memberOf fabric.Image.filters
79673   * @extends fabric.Image.filters.BaseFilter
79674   * @see {@link fabric.Image.filters.Blur#initialize} for constructor definition
79675   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
79676   * @example
79677   * var filter = new fabric.Image.filters.Blur({
79678   *   blur: 0.5
79679   * });
79680   * object.filters.push(filter);
79681   * object.applyFilters();
79682   * canvas.renderAll();
79683   */
79684  filters.Blur = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blur.prototype */ {
79685
79686    type: 'Blur',
79687
79688    /*
79689'gl_FragColor = vec4(0.0);',
79690'gl_FragColor += texture2D(texture, vTexCoord + -7 * uDelta)*0.0044299121055113265;',
79691'gl_FragColor += texture2D(texture, vTexCoord + -6 * uDelta)*0.00895781211794;',
79692'gl_FragColor += texture2D(texture, vTexCoord + -5 * uDelta)*0.0215963866053;',
79693'gl_FragColor += texture2D(texture, vTexCoord + -4 * uDelta)*0.0443683338718;',
79694'gl_FragColor += texture2D(texture, vTexCoord + -3 * uDelta)*0.0776744219933;',
79695'gl_FragColor += texture2D(texture, vTexCoord + -2 * uDelta)*0.115876621105;',
79696'gl_FragColor += texture2D(texture, vTexCoord + -1 * uDelta)*0.147308056121;',
79697'gl_FragColor += texture2D(texture, vTexCoord              )*0.159576912161;',
79698'gl_FragColor += texture2D(texture, vTexCoord + 1 * uDelta)*0.147308056121;',
79699'gl_FragColor += texture2D(texture, vTexCoord + 2 * uDelta)*0.115876621105;',
79700'gl_FragColor += texture2D(texture, vTexCoord + 3 * uDelta)*0.0776744219933;',
79701'gl_FragColor += texture2D(texture, vTexCoord + 4 * uDelta)*0.0443683338718;',
79702'gl_FragColor += texture2D(texture, vTexCoord + 5 * uDelta)*0.0215963866053;',
79703'gl_FragColor += texture2D(texture, vTexCoord + 6 * uDelta)*0.00895781211794;',
79704'gl_FragColor += texture2D(texture, vTexCoord + 7 * uDelta)*0.0044299121055113265;',
79705*/
79706
79707    /* eslint-disable max-len */
79708    fragmentSource: 'precision highp float;\n' +
79709      'uniform sampler2D uTexture;\n' +
79710      'uniform vec2 uDelta;\n' +
79711      'varying vec2 vTexCoord;\n' +
79712      'const float nSamples = 15.0;\n' +
79713      'vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\n' +
79714      'float random(vec3 scale) {\n' +
79715        /* use the fragment position for a different seed per-pixel */
79716        'return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n' +
79717      '}\n' +
79718      'void main() {\n' +
79719        'vec4 color = vec4(0.0);\n' +
79720        'float total = 0.0;\n' +
79721        'float offset = random(v3offset);\n' +
79722        'for (float t = -nSamples; t <= nSamples; t++) {\n' +
79723          'float percent = (t + offset - 0.5) / nSamples;\n' +
79724          'float weight = 1.0 - abs(percent);\n' +
79725          'color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\n' +
79726          'total += weight;\n' +
79727        '}\n' +
79728        'gl_FragColor = color / total;\n' +
79729      '}',
79730    /* eslint-enable max-len */
79731
79732    /**
79733     * blur value, in percentage of image dimensions.
79734     * specific to keep the image blur constant at different resolutions
79735     * range between 0 and 1.
79736     */
79737    blur: 0,
79738
79739    mainParameter: 'blur',
79740
79741    applyTo: function(options) {
79742      if (options.webgl) {
79743        // this aspectRatio is used to give the same blur to vertical and horizontal
79744        this.aspectRatio = options.sourceWidth / options.sourceHeight;
79745        options.passes++;
79746        this._setupFrameBuffer(options);
79747        this.horizontal = true;
79748        this.applyToWebGL(options);
79749        this._swapTextures(options);
79750        this._setupFrameBuffer(options);
79751        this.horizontal = false;
79752        this.applyToWebGL(options);
79753        this._swapTextures(options);
79754      }
79755      else {
79756        this.applyTo2d(options);
79757      }
79758    },
79759
79760    applyTo2d: function(options) {
79761      // paint canvasEl with current image data.
79762      //options.ctx.putImageData(options.imageData, 0, 0);
79763      options.imageData = this.simpleBlur(options);
79764    },
79765
79766    simpleBlur: function(options) {
79767      var resources = options.filterBackend.resources, canvas1, canvas2,
79768          width = options.imageData.width,
79769          height = options.imageData.height;
79770
79771      if (!resources.blurLayer1) {
79772        resources.blurLayer1 = fabric.util.createCanvasElement();
79773        resources.blurLayer2 = fabric.util.createCanvasElement();
79774      }
79775      canvas1 = resources.blurLayer1;
79776      canvas2 = resources.blurLayer2;
79777      if (canvas1.width !== width || canvas1.height !== height) {
79778        canvas2.width = canvas1.width = width;
79779        canvas2.height = canvas1.height = height;
79780      }
79781      var ctx1 = canvas1.getContext('2d'),
79782          ctx2 = canvas2.getContext('2d'),
79783          nSamples = 15,
79784          random, percent, j, i,
79785          blur = this.blur * 0.06 * 0.5;
79786
79787      // load first canvas
79788      ctx1.putImageData(options.imageData, 0, 0);
79789      ctx2.clearRect(0, 0, width, height);
79790
79791      for (i = -nSamples; i <= nSamples; i++) {
79792        random = (Math.random() - 0.5) / 4;
79793        percent = i / nSamples;
79794        j = blur * percent * width + random;
79795        ctx2.globalAlpha = 1 - Math.abs(percent);
79796        ctx2.drawImage(canvas1, j, random);
79797        ctx1.drawImage(canvas2, 0, 0);
79798        ctx2.globalAlpha = 1;
79799        ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
79800      }
79801      for (i = -nSamples; i <= nSamples; i++) {
79802        random = (Math.random() - 0.5) / 4;
79803        percent = i / nSamples;
79804        j = blur * percent * height + random;
79805        ctx2.globalAlpha = 1 - Math.abs(percent);
79806        ctx2.drawImage(canvas1, random, j);
79807        ctx1.drawImage(canvas2, 0, 0);
79808        ctx2.globalAlpha = 1;
79809        ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
79810      }
79811      options.ctx.drawImage(canvas1, 0, 0);
79812      var newImageData = options.ctx.getImageData(0, 0, canvas1.width, canvas1.height);
79813      ctx1.globalAlpha = 1;
79814      ctx1.clearRect(0, 0, canvas1.width, canvas1.height);
79815      return newImageData;
79816    },
79817
79818    /**
79819     * Return WebGL uniform locations for this filter's shader.
79820     *
79821     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
79822     * @param {WebGLShaderProgram} program This filter's compiled shader program.
79823     */
79824    getUniformLocations: function(gl, program) {
79825      return {
79826        delta: gl.getUniformLocation(program, 'uDelta'),
79827      };
79828    },
79829
79830    /**
79831     * Send data from this filter to its shader program's uniforms.
79832     *
79833     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
79834     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
79835     */
79836    sendUniformData: function(gl, uniformLocations) {
79837      var delta = this.chooseRightDelta();
79838      gl.uniform2fv(uniformLocations.delta, delta);
79839    },
79840
79841    /**
79842     * choose right value of image percentage to blur with
79843     * @returns {Array} a numeric array with delta values
79844     */
79845    chooseRightDelta: function() {
79846      var blurScale = 1, delta = [0, 0], blur;
79847      if (this.horizontal) {
79848        if (this.aspectRatio > 1) {
79849          // image is wide, i want to shrink radius horizontal
79850          blurScale = 1 / this.aspectRatio;
79851        }
79852      }
79853      else {
79854        if (this.aspectRatio < 1) {
79855          // image is tall, i want to shrink radius vertical
79856          blurScale = this.aspectRatio;
79857        }
79858      }
79859      blur = blurScale * this.blur * 0.12;
79860      if (this.horizontal) {
79861        delta[0] = blur;
79862      }
79863      else {
79864        delta[1] = blur;
79865      }
79866      return delta;
79867    },
79868  });
79869
79870  /**
79871   * Deserialize a JSON definition of a BlurFilter into a concrete instance.
79872   */
79873  filters.Blur.fromObject = fabric.Image.filters.BaseFilter.fromObject;
79874
79875})( true ? exports : 
vendor: 10,339 bytes, lines 79875-80196
79875this);
79876
79877
79878(function(global) {
79879
79880  'use strict';
79881
79882  var fabric  = global.fabric || (global.fabric = { }),
79883      filters = fabric.Image.filters,
79884      createClass = fabric.util.createClass;
79885
79886  /**
79887   * Gamma filter class
79888   * @class fabric.Image.filters.Gamma
79889   * @memberOf fabric.Image.filters
79890   * @extends fabric.Image.filters.BaseFilter
79891   * @see {@link fabric.Image.filters.Gamma#initialize} for constructor definition
79892   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
79893   * @example
79894   * var filter = new fabric.Image.filters.Gamma({
79895   *   gamma: [1, 0.5, 2.1]
79896   * });
79897   * object.filters.push(filter);
79898   * object.applyFilters();
79899   */
79900  filters.Gamma = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Gamma.prototype */ {
79901
79902    /**
79903     * Filter type
79904     * @param {String} type
79905     * @default
79906     */
79907    type: 'Gamma',
79908
79909    fragmentSource: 'precision highp float;\n' +
79910      'uniform sampler2D uTexture;\n' +
79911      'uniform vec3 uGamma;\n' +
79912      'varying vec2 vTexCoord;\n' +
79913      'void main() {\n' +
79914        'vec4 color = texture2D(uTexture, vTexCoord);\n' +
79915        'vec3 correction = (1.0 / uGamma);\n' +
79916        'color.r = pow(color.r, correction.r);\n' +
79917        'color.g = pow(color.g, correction.g);\n' +
79918        'color.b = pow(color.b, correction.b);\n' +
79919        'gl_FragColor = color;\n' +
79920        'gl_FragColor.rgb *= color.a;\n' +
79921      '}',
79922
79923    /**
79924     * Gamma array value, from 0.01 to 2.2.
79925     * @param {Array} gamma
79926     * @default
79927     */
79928    gamma: [1, 1, 1],
79929
79930    /**
79931     * Describe the property that is the filter parameter
79932     * @param {String} m
79933     * @default
79934     */
79935    mainParameter: 'gamma',
79936
79937    /**
79938     * Constructor
79939     * @param {Object} [options] Options object
79940     */
79941    initialize: function(options) {
79942      this.gamma = [1, 1, 1];
79943      filters.BaseFilter.prototype.initialize.call(this, options);
79944    },
79945
79946    /**
79947     * Apply the Gamma operation to a Uint8Array representing the pixels of an image.
79948     *
79949     * @param {Object} options
79950     * @param {ImageData} options.imageData The Uint8Array to be filtered.
79951     */
79952    applyTo2d: function(options) {
79953      var imageData = options.imageData, data = imageData.data,
79954          gamma = this.gamma, len = data.length,
79955          rInv = 1 / gamma[0], gInv = 1 / gamma[1],
79956          bInv = 1 / gamma[2], i;
79957
79958      if (!this.rVals) {
79959        // eslint-disable-next-line
79960        this.rVals = new Uint8Array(256);
79961        // eslint-disable-next-line
79962        this.gVals = new Uint8Array(256);
79963        // eslint-disable-next-line
79964        this.bVals = new Uint8Array(256);
79965      }
79966
79967      // This is an optimization - pre-compute a look-up table for each color channel
79968      // instead of performing these pow calls for each pixel in the image.
79969      for (i = 0, len = 256; i < len; i++) {
79970        this.rVals[i] = Math.pow(i / 255, rInv) * 255;
79971        this.gVals[i] = Math.pow(i / 255, gInv) * 255;
79972        this.bVals[i] = Math.pow(i / 255, bInv) * 255;
79973      }
79974      for (i = 0, len = data.length; i < len; i += 4) {
79975        data[i] = this.rVals[data[i]];
79976        data[i + 1] = this.gVals[data[i + 1]];
79977        data[i + 2] = this.bVals[data[i + 2]];
79978      }
79979    },
79980
79981    /**
79982     * Return WebGL uniform locations for this filter's shader.
79983     *
79984     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
79985     * @param {WebGLShaderProgram} program This filter's compiled shader program.
79986     */
79987    getUniformLocations: function(gl, program) {
79988      return {
79989        uGamma: gl.getUniformLocation(program, 'uGamma'),
79990      };
79991    },
79992
79993    /**
79994     * Send data from this filter to its shader program's uniforms.
79995     *
79996     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
79997     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
79998     */
79999    sendUniformData: function(gl, uniformLocations) {
80000      gl.uniform3fv(uniformLocations.uGamma, this.gamma);
80001    },
80002  });
80003
80004  /**
80005   * Returns filter instance from an object representation
80006   * @static
80007   * @param {Object} object Object to create an instance from
80008   * @param {function} [callback] to be invoked after filter creation
80009   * @return {fabric.Image.filters.Gamma} Instance of fabric.Image.filters.Gamma
80010   */
80011  fabric.Image.filters.Gamma.fromObject = fabric.Image.filters.BaseFilter.fromObject;
80012
80013})( true ? exports : this);
80014
80015
80016(function(global) {
80017
80018  'use strict';
80019
80020  var fabric  = global.fabric || (global.fabric = { }),
80021      filters = fabric.Image.filters,
80022      createClass = fabric.util.createClass;
80023
80024  /**
80025   * A container class that knows how to apply a sequence of filters to an input image.
80026   */
80027  filters.Composed = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Composed.prototype */ {
80028
80029    type: 'Composed',
80030
80031    /**
80032     * A non sparse array of filters to apply
80033     */
80034    subFilters: [],
80035
80036    /**
80037     * Constructor
80038     * @param {Object} [options] Options object
80039     */
80040    initialize: function(options) {
80041      this.callSuper('initialize', options);
80042      // create a new array instead mutating the prototype with push
80043      this.subFilters = this.subFilters.slice(0);
80044    },
80045
80046    /**
80047     * Apply this container's filters to the input image provided.
80048     *
80049     * @param {Object} options
80050     * @param {Number} options.passes The number of filters remaining to be applied.
80051     */
80052    applyTo: function(options) {
80053      options.passes += this.subFilters.length - 1;
80054      this.subFilters.forEach(function(filter) {
80055        filter.applyTo(options);
80056      });
80057    },
80058
80059    /**
80060     * Serialize this filter into JSON.
80061     *
80062     * @returns {Object} A JSON representation of this filter.
80063     */
80064    toObject: function() {
80065      return fabric.util.object.extend(this.callSuper('toObject'), {
80066        subFilters: this.subFilters.map(function(filter) { return filter.toObject(); }),
80067      });
80068    },
80069
80070    isNeutralState: function() {
80071      return !this.subFilters.some(function(filter) { return !filter.isNeutralState(); });
80072    }
80073  });
80074
80075  /**
80076   * Deserialize a JSON definition of a ComposedFilter into a concrete instance.
80077   */
80078  fabric.Image.filters.Composed.fromObject = function(object, callback) {
80079    var filters = object.subFilters || [],
80080        subFilters = filters.map(function(filter) {
80081          return new fabric.Image.filters[filter.type](filter);
80082        }),
80083        instance = new fabric.Image.filters.Composed({ subFilters: subFilters });
80084    callback && callback(instance);
80085    return instance;
80086  };
80087})( true ? exports : this);
80088
80089
80090(function(global) {
80091
80092  'use strict';
80093
80094  var fabric  = global.fabric || (global.fabric = { }),
80095      filters = fabric.Image.filters,
80096      createClass = fabric.util.createClass;
80097
80098  /**
80099   * HueRotation filter class
80100   * @class fabric.Image.filters.HueRotation
80101   * @memberOf fabric.Image.filters
80102   * @extends fabric.Image.filters.BaseFilter
80103   * @see {@link fabric.Image.filters.HueRotation#initialize} for constructor definition
80104   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
80105   * @example
80106   * var filter = new fabric.Image.filters.HueRotation({
80107   *   rotation: -0.5
80108   * });
80109   * object.filters.push(filter);
80110   * object.applyFilters();
80111   */
80112  filters.HueRotation = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.HueRotation.prototype */ {
80113
80114    /**
80115     * Filter type
80116     * @param {String} type
80117     * @default
80118     */
80119    type: 'HueRotation',
80120
80121    /**
80122     * HueRotation value, from -1 to 1.
80123     * the unit is radians
80124     * @param {Number} myParameter
80125     * @default
80126     */
80127    rotation: 0,
80128
80129    /**
80130     * Describe the property that is the filter parameter
80131     * @param {String} m
80132     * @default
80133     */
80134    mainParameter: 'rotation',
80135
80136    calculateMatrix: function() {
80137      var rad = this.rotation * Math.PI, cos = fabric.util.cos(rad), sin = fabric.util.sin(rad),
80138          aThird = 1 / 3, aThirdSqtSin = Math.sqrt(aThird) * sin, OneMinusCos = 1 - cos;
80139      this.matrix = [
80140        1, 0, 0, 0, 0,
80141        0, 1, 0, 0, 0,
80142        0, 0, 1, 0, 0,
80143        0, 0, 0, 1, 0
80144      ];
80145      this.matrix[0] = cos + OneMinusCos / 3;
80146      this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin;
80147      this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin;
80148      this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin;
80149      this.matrix[6] = cos + aThird * OneMinusCos;
80150      this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin;
80151      this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin;
80152      this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin;
80153      this.matrix[12] = cos + aThird * OneMinusCos;
80154    },
80155
80156    /**
80157     * HueRotation isNeutralState implementation
80158     * Used only in image applyFilters to discard filters that will not have an effect
80159     * on the image
80160     * @param {Object} options
80161     **/
80162    isNeutralState: function(options) {
80163      this.calculateMatrix();
80164      return filters.BaseFilter.prototype.isNeutralState.call(this, options);
80165    },
80166
80167    /**
80168     * Apply this filter to the input image data provided.
80169     *
80170     * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.
80171     *
80172     * @param {Object} options
80173     * @param {Number} options.passes The number of filters remaining to be executed
80174     * @param {Boolean} options.webgl Whether to use webgl to render the filter.
80175     * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.
80176     * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.
80177     * @param {WebGLRenderingContext} options.context The GL context used for rendering.
80178     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
80179     */
80180    applyTo: function(options) {
80181      this.calculateMatrix();
80182      filters.BaseFilter.prototype.applyTo.call(this, options);
80183    },
80184
80185  });
80186
80187  /**
80188   * Returns filter instance from an object representation
80189   * @static
80190   * @param {Object} object Object to create an instance from
80191   * @param {function} [callback] to be invoked after filter creation
80192   * @return {fabric.Image.filters.HueRotation} Instance of fabric.Image.filters.HueRotation
80193   */
80194  fabric.Image.filters.HueRotation.fromObject = fabric.Image.filters.BaseFilter.fromObject;
80195
80196})( true ? exports : this
vendor: 57,209 bytes, lines 80196-81905
80196);
80197
80198
80199(function(global) {
80200
80201  'use strict';
80202
80203  var fabric = global.fabric || (global.fabric = { }),
80204      clone = fabric.util.object.clone;
80205
80206  if (fabric.Text) {
80207    fabric.warn('fabric.Text is already defined');
80208    return;
80209  }
80210
80211  var additionalProps =
80212    ('fontFamily fontWeight fontSize text underline overline linethrough' +
80213    ' textAlign fontStyle lineHeight textBackgroundColor charSpacing styles' +
80214    ' direction path pathStartOffset pathSide').split(' ');
80215
80216  /**
80217   * Text class
80218   * @class fabric.Text
80219   * @extends fabric.Object
80220   * @return {fabric.Text} thisArg
80221   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text}
80222   * @see {@link fabric.Text#initialize} for constructor definition
80223   */
80224  fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ {
80225
80226    /**
80227     * Properties which when set cause object to change dimensions
80228     * @type Array
80229     * @private
80230     */
80231    _dimensionAffectingProps: [
80232      'fontSize',
80233      'fontWeight',
80234      'fontFamily',
80235      'fontStyle',
80236      'lineHeight',
80237      'text',
80238      'charSpacing',
80239      'textAlign',
80240      'styles',
80241      'path',
80242      'pathStartOffset',
80243      'pathSide'
80244    ],
80245
80246    /**
80247     * @private
80248     */
80249    _reNewline: /\r?\n/,
80250
80251    /**
80252     * Use this regular expression to filter for whitespaces that is not a new line.
80253     * Mostly used when text is 'justify' aligned.
80254     * @private
80255     */
80256    _reSpacesAndTabs: /[ \t\r]/g,
80257
80258    /**
80259     * Use this regular expression to filter for whitespace that is not a new line.
80260     * Mostly used when text is 'justify' aligned.
80261     * @private
80262     */
80263    _reSpaceAndTab: /[ \t\r]/,
80264
80265    /**
80266     * Use this regular expression to filter consecutive groups of non spaces.
80267     * Mostly used when text is 'justify' aligned.
80268     * @private
80269     */
80270    _reWords: /\S+/g,
80271
80272    /**
80273     * Type of an object
80274     * @type String
80275     * @default
80276     */
80277    type:                 'text',
80278
80279    /**
80280     * Font size (in pixels)
80281     * @type Number
80282     * @default
80283     */
80284    fontSize:             40,
80285
80286    /**
80287     * Font weight (e.g. bold, normal, 400, 600, 800)
80288     * @type {(Number|String)}
80289     * @default
80290     */
80291    fontWeight:           'normal',
80292
80293    /**
80294     * Font family
80295     * @type String
80296     * @default
80297     */
80298    fontFamily:           'Times New Roman',
80299
80300    /**
80301     * Text decoration underline.
80302     * @type Boolean
80303     * @default
80304     */
80305    underline:       false,
80306
80307    /**
80308     * Text decoration overline.
80309     * @type Boolean
80310     * @default
80311     */
80312    overline:       false,
80313
80314    /**
80315     * Text decoration linethrough.
80316     * @type Boolean
80317     * @default
80318     */
80319    linethrough:       false,
80320
80321    /**
80322     * Text alignment. Possible values: "left", "center", "right", "justify",
80323     * "justify-left", "justify-center" or "justify-right".
80324     * @type String
80325     * @default
80326     */
80327    textAlign:            'left',
80328
80329    /**
80330     * Font style . Possible values: "", "normal", "italic" or "oblique".
80331     * @type String
80332     * @default
80333     */
80334    fontStyle:            'normal',
80335
80336    /**
80337     * Line height
80338     * @type Number
80339     * @default
80340     */
80341    lineHeight:           1.16,
80342
80343    /**
80344     * Superscript schema object (minimum overlap)
80345     * @type {Object}
80346     * @default
80347     */
80348    superscript: {
80349      size:      0.60, // fontSize factor
80350      baseline: -0.35  // baseline-shift factor (upwards)
80351    },
80352
80353    /**
80354     * Subscript schema object (minimum overlap)
80355     * @type {Object}
80356     * @default
80357     */
80358    subscript: {
80359      size:      0.60, // fontSize factor
80360      baseline:  0.11  // baseline-shift factor (downwards)
80361    },
80362
80363    /**
80364     * Background color of text lines
80365     * @type String
80366     * @default
80367     */
80368    textBackgroundColor:  '',
80369
80370    /**
80371     * List of properties to consider when checking if
80372     * state of an object is changed ({@link fabric.Object#hasStateChanged})
80373     * as well as for history (undo/redo) purposes
80374     * @type Array
80375     */
80376    stateProperties: fabric.Object.prototype.stateProperties.concat(additionalProps),
80377
80378    /**
80379     * List of properties to consider when checking if cache needs refresh
80380     * @type Array
80381     */
80382    cacheProperties: fabric.Object.prototype.cacheProperties.concat(additionalProps),
80383
80384    /**
80385     * When defined, an object is rendered via stroke and this property specifies its color.
80386     * <b>Backwards incompatibility note:</b> This property was named "strokeStyle" until v1.1.6
80387     * @type String
80388     * @default
80389     */
80390    stroke:               null,
80391
80392    /**
80393     * Shadow object representing shadow of this shape.
80394     * <b>Backwards incompatibility note:</b> This property was named "textShadow" (String) until v1.2.11
80395     * @type fabric.Shadow
80396     * @default
80397     */
80398    shadow:               null,
80399
80400    /**
80401     * fabric.Path that the text should follow.
80402     * since 4.6.0 the path will be drawn automatically.
80403     * if you want to make the path visible, give it a stroke and strokeWidth or fill value
80404     * if you want it to be hidden, assign visible = false to the path.
80405     * This feature is in BETA, and SVG import/export is not yet supported.
80406     * @type fabric.Path
80407     * @example
80408     * var textPath = new fabric.Text('Text on a path', {
80409     *     top: 150,
80410     *     left: 150,
80411     *     textAlign: 'center',
80412     *     charSpacing: -50,
80413     *     path: new fabric.Path('M 0 0 C 50 -100 150 -100 200 0', {
80414     *         strokeWidth: 1,
80415     *         visible: false
80416     *     }),
80417     *     pathSide: 'left',
80418     *     pathStartOffset: 0
80419     * });
80420     * @default
80421     */
80422    path:               null,
80423
80424    /**
80425     * Offset amount for text path starting position
80426     * Only used when text has a path
80427     * @type Number
80428     * @default
80429     */
80430    pathStartOffset:               0,
80431
80432    /**
80433     * Which side of the path the text should be drawn on.
80434     * Only used when text has a path
80435     * @type {String} 'left|right'
80436     * @default
80437     */
80438    pathSide:               'left',
80439
80440    /**
80441     * @private
80442     */
80443    _fontSizeFraction: 0.222,
80444
80445    /**
80446     * @private
80447     */
80448    offsets: {
80449      underline: 0.10,
80450      linethrough: -0.315,
80451      overline: -0.88
80452    },
80453
80454    /**
80455     * Text Line proportion to font Size (in pixels)
80456     * @type Number
80457     * @default
80458     */
80459    _fontSizeMult:             1.13,
80460
80461    /**
80462     * additional space between characters
80463     * expressed in thousands of em unit
80464     * @type Number
80465     * @default
80466     */
80467    charSpacing:             0,
80468
80469    /**
80470     * Object containing character styles - top-level properties -> line numbers,
80471     * 2nd-level properties - character numbers
80472     * @type Object
80473     * @default
80474     */
80475    styles: null,
80476
80477    /**
80478     * Reference to a context to measure text char or couple of chars
80479     * the cacheContext of the canvas will be used or a freshly created one if the object is not on canvas
80480     * once created it will be referenced on fabric._measuringContext to avoid creating a canvas for every
80481     * text object created.
80482     * @type {CanvasRenderingContext2D}
80483     * @default
80484     */
80485    _measuringContext: null,
80486
80487    /**
80488     * Baseline shift, styles only, keep at 0 for the main text object
80489     * @type {Number}
80490     * @default
80491     */
80492    deltaY: 0,
80493
80494    /**
80495     * WARNING: EXPERIMENTAL. NOT SUPPORTED YET
80496     * determine the direction of the text.
80497     * This has to be set manually together with textAlign and originX for proper
80498     * experience.
80499     * some interesting link for the future
80500     * https://www.w3.org/International/questions/qa-bidi-unicode-controls
80501     * @since 4.5.0
80502     * @type {String} 'ltr|rtl'
80503     * @default
80504     */
80505    direction: 'ltr',
80506
80507    /**
80508     * Array of properties that define a style unit (of 'styles').
80509     * @type {Array}
80510     * @default
80511     */
80512    _styleProperties: [
80513      'stroke',
80514      'strokeWidth',
80515      'fill',
80516      'fontFamily',
80517      'fontSize',
80518      'fontWeight',
80519      'fontStyle',
80520      'underline',
80521      'overline',
80522      'linethrough',
80523      'deltaY',
80524      'textBackgroundColor',
80525    ],
80526
80527    /**
80528     * contains characters bounding boxes
80529     */
80530    __charBounds: [],
80531
80532    /**
80533     * use this size when measuring text. To avoid IE11 rounding errors
80534     * @type {Number}
80535     * @default
80536     * @readonly
80537     * @private
80538     */
80539    CACHE_FONT_SIZE: 400,
80540
80541    /**
80542     * contains the min text width to avoid getting 0
80543     * @type {Number}
80544     * @default
80545     */
80546    MIN_TEXT_WIDTH: 2,
80547
80548    /**
80549     * Constructor
80550     * @param {String} text Text string
80551     * @param {Object} [options] Options object
80552     * @return {fabric.Text} thisArg
80553     */
80554    initialize: function(text, options) {
80555      this.styles = options ? (options.styles || { }) : { };
80556      this.text = text;
80557      this.__skipDimension = true;
80558      this.callSuper('initialize', options);
80559      if (this.path) {
80560        this.setPathInfo();
80561      }
80562      this.__skipDimension = false;
80563      this.initDimensions();
80564      this.setCoords();
80565      this.setupState({ propertySet: '_dimensionAffectingProps' });
80566    },
80567
80568    /**
80569     * If text has a path, it will add the extra information needed
80570     * for path and text calculations
80571     * @return {fabric.Text} thisArg
80572     */
80573    setPathInfo: function() {
80574      var path = this.path;
80575      if (path) {
80576        path.segmentsInfo = fabric.util.getPathSegmentsInfo(path.path);
80577      }
80578    },
80579
80580    /**
80581     * Return a context for measurement of text string.
80582     * if created it gets stored for reuse
80583     * @param {String} text Text string
80584     * @param {Object} [options] Options object
80585     * @return {fabric.Text} thisArg
80586     */
80587    getMeasuringContext: function() {
80588      // if we did not return we have to measure something.
80589      if (!fabric._measuringContext) {
80590        fabric._measuringContext = this.canvas && this.canvas.contextCache ||
80591          fabric.util.createCanvasElement().getContext('2d');
80592      }
80593      return fabric._measuringContext;
80594    },
80595
80596    /**
80597     * @private
80598     * Divides text into lines of text and lines of graphemes.
80599     */
80600    _splitText: function() {
80601      var newLines = this._splitTextIntoLines(this.text);
80602      this.textLines = newLines.lines;
80603      this._textLines = newLines.graphemeLines;
80604      this._unwrappedTextLines = newLines._unwrappedLines;
80605      this._text = newLines.graphemeText;
80606      return newLines;
80607    },
80608
80609    /**
80610     * Initialize or update text dimensions.
80611     * Updates this.width and this.height with the proper values.
80612     * Does not return dimensions.
80613     */
80614    initDimensions: function() {
80615      if (this.__skipDimension) {
80616        return;
80617      }
80618      this._splitText();
80619      this._clearCache();
80620      if (this.path) {
80621        this.width = this.path.width;
80622        this.height = this.path.height;
80623      }
80624      else {
80625        this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH;
80626        this.height = this.calcTextHeight();
80627      }
80628      if (this.textAlign.indexOf('justify') !== -1) {
80629        // once text is measured we need to make space fatter to make justified text.
80630        this.enlargeSpaces();
80631      }
80632      this.saveState({ propertySet: '_dimensionAffectingProps' });
80633    },
80634
80635    /**
80636     * Enlarge space boxes and shift the others
80637     */
80638    enlargeSpaces: function() {
80639      var diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces;
80640      for (var i = 0, len = this._textLines.length; i < len; i++) {
80641        if (this.textAlign !== 'justify' && (i === len - 1 || this.isEndOfWrapping(i))) {
80642          continue;
80643        }
80644        accumulatedSpace = 0;
80645        line = this._textLines[i];
80646        currentLineWidth = this.getLineWidth(i);
80647        if (currentLineWidth < this.width && (spaces = this.textLines[i].match(this._reSpacesAndTabs))) {
80648          numberOfSpaces = spaces.length;
80649          diffSpace = (this.width - currentLineWidth) / numberOfSpaces;
80650          for (var j = 0, jlen = line.length; j <= jlen; j++) {
80651            charBound = this.__charBounds[i][j];
80652            if (this._reSpaceAndTab.test(line[j])) {
80653              charBound.width += diffSpace;
80654              charBound.kernedWidth += diffSpace;
80655              charBound.left += accumulatedSpace;
80656              accumulatedSpace += diffSpace;
80657            }
80658            else {
80659              charBound.left += accumulatedSpace;
80660            }
80661          }
80662        }
80663      }
80664    },
80665
80666    /**
80667     * Detect if the text line is ended with an hard break
80668     * text and itext do not have wrapping, return false
80669     * @return {Boolean}
80670     */
80671    isEndOfWrapping: function(lineIndex) {
80672      return lineIndex === this._textLines.length - 1;
80673    },
80674
80675    /**
80676     * Detect if a line has a linebreak and so we need to account for it when moving
80677     * and counting style.
80678     * It return always for text and Itext.
80679     * @return Number
80680     */
80681    missingNewlineOffset: function() {
80682      return 1;
80683    },
80684
80685    /**
80686     * Returns string representation of an instance
80687     * @return {String} String representation of text object
80688     */
80689    toString: function() {
80690      return '#<fabric.Text (' + this.complexity() +
80691        '): { "text": "' + this.text + '", "fontFamily": "' + this.fontFamily + '" }>';
80692    },
80693
80694    /**
80695     * Return the dimension and the zoom level needed to create a cache canvas
80696     * big enough to host the object to be cached.
80697     * @private
80698     * @param {Object} dim.x width of object to be cached
80699     * @param {Object} dim.y height of object to be cached
80700     * @return {Object}.width width of canvas
80701     * @return {Object}.height height of canvas
80702     * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache
80703     * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache
80704     */
80705    _getCacheCanvasDimensions: function() {
80706      var dims = this.callSuper('_getCacheCanvasDimensions');
80707      var fontSize = this.fontSize;
80708      dims.width += fontSize * dims.zoomX;
80709      dims.height += fontSize * dims.zoomY;
80710      return dims;
80711    },
80712
80713    /**
80714     * @private
80715     * @param {CanvasRenderingContext2D} ctx Context to render on
80716     */
80717    _render: function(ctx) {
80718      var path = this.path;
80719      path && !path.isNotVisible() && path._render(ctx);
80720      this._setTextStyles(ctx);
80721      this._renderTextLinesBackground(ctx);
80722      this._renderTextDecoration(ctx, 'underline');
80723      this._renderText(ctx);
80724      this._renderTextDecoration(ctx, 'overline');
80725      this._renderTextDecoration(ctx, 'linethrough');
80726    },
80727
80728    /**
80729     * @private
80730     * @param {CanvasRenderingContext2D} ctx Context to render on
80731     */
80732    _renderText: function(ctx) {
80733      if (this.paintFirst === 'stroke') {
80734        this._renderTextStroke(ctx);
80735        this._renderTextFill(ctx);
80736      }
80737      else {
80738        this._renderTextFill(ctx);
80739        this._renderTextStroke(ctx);
80740      }
80741    },
80742
80743    /**
80744     * Set the font parameter of the context with the object properties or with charStyle
80745     * @private
80746     * @param {CanvasRenderingContext2D} ctx Context to render on
80747     * @param {Object} [charStyle] object with font style properties
80748     * @param {String} [charStyle.fontFamily] Font Family
80749     * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix )
80750     * @param {String} [charStyle.fontWeight] Font weight
80751     * @param {String} [charStyle.fontStyle] Font style (italic|normal)
80752     */
80753    _setTextStyles: function(ctx, charStyle, forMeasuring) {
80754      ctx.textBaseline = 'alphabetic';
80755      ctx.font = this._getFontDeclaration(charStyle, forMeasuring);
80756    },
80757
80758    /**
80759     * calculate and return the text Width measuring each line.
80760     * @private
80761     * @param {CanvasRenderingContext2D} ctx Context to render on
80762     * @return {Number} Maximum width of fabric.Text object
80763     */
80764    calcTextWidth: function() {
80765      var maxWidth = this.getLineWidth(0);
80766
80767      for (var i = 1, len = this._textLines.length; i < len; i++) {
80768        var currentLineWidth = this.getLineWidth(i);
80769        if (currentLineWidth > maxWidth) {
80770          maxWidth = currentLineWidth;
80771        }
80772      }
80773      return maxWidth;
80774    },
80775
80776    /**
80777     * @private
80778     * @param {String} method Method name ("fillText" or "strokeText")
80779     * @param {CanvasRenderingContext2D} ctx Context to render on
80780     * @param {String} line Text to render
80781     * @param {Number} left Left position of text
80782     * @param {Number} top Top position of text
80783     * @param {Number} lineIndex Index of a line in a text
80784     */
80785    _renderTextLine: function(method, ctx, line, left, top, lineIndex) {
80786      this._renderChars(method, ctx, line, left, top, lineIndex);
80787    },
80788
80789    /**
80790     * Renders the text background for lines, taking care of style
80791     * @private
80792     * @param {CanvasRenderingContext2D} ctx Context to render on
80793     */
80794    _renderTextLinesBackground: function(ctx) {
80795      if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) {
80796        return;
80797      }
80798      var heightOfLine,
80799          lineLeftOffset, originalFill = ctx.fillStyle,
80800          line, lastColor,
80801          leftOffset = this._getLeftOffset(),
80802          lineTopOffset = this._getTopOffset(),
80803          boxStart = 0, boxWidth = 0, charBox, currentColor, path = this.path,
80804          drawStart;
80805
80806      for (var i = 0, len = this._textLines.length; i < len; i++) {
80807        heightOfLine = this.getHeightOfLine(i);
80808        if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor', i)) {
80809          lineTopOffset += heightOfLine;
80810          continue;
80811        }
80812        line = this._textLines[i];
80813        lineLeftOffset = this._getLineLeftOffset(i);
80814        boxWidth = 0;
80815        boxStart = 0;
80816        lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');
80817        for (var j = 0, jlen = line.length; j < jlen; j++) {
80818          charBox = this.__charBounds[i][j];
80819          currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');
80820          if (path) {
80821            ctx.save();
80822            ctx.translate(charBox.renderLeft, charBox.renderTop);
80823            ctx.rotate(charBox.angle);
80824            ctx.fillStyle = currentColor;
80825            currentColor && ctx.fillRect(
80826              -charBox.width / 2,
80827              -heightOfLine / this.lineHeight * (1 - this._fontSizeFraction),
80828              charBox.width,
80829              heightOfLine / this.lineHeight
80830            );
80831            ctx.restore();
80832          }
80833          else if (currentColor !== lastColor) {
80834            drawStart = leftOffset + lineLeftOffset + boxStart;
80835            if (this.direction === 'rtl') {
80836              drawStart = this.width - drawStart - boxWidth;
80837            }
80838            ctx.fillStyle = lastColor;
80839            lastColor && ctx.fillRect(
80840              drawStart,
80841              lineTopOffset,
80842              boxWidth,
80843              heightOfLine / this.lineHeight
80844            );
80845            boxStart = charBox.left;
80846            boxWidth = charBox.width;
80847            lastColor = currentColor;
80848          }
80849          else {
80850            boxWidth += charBox.kernedWidth;
80851          }
80852        }
80853        if (currentColor && !path) {
80854          drawStart = leftOffset + lineLeftOffset + boxStart;
80855          if (this.direction === 'rtl') {
80856            drawStart = this.width - drawStart - boxWidth;
80857          }
80858          ctx.fillStyle = currentColor;
80859          ctx.fillRect(
80860            drawStart,
80861            lineTopOffset,
80862            boxWidth,
80863            heightOfLine / this.lineHeight
80864          );
80865        }
80866        lineTopOffset += heightOfLine;
80867      }
80868      ctx.fillStyle = originalFill;
80869      // if there is text background color no
80870      // other shadows should be casted
80871      this._removeShadow(ctx);
80872    },
80873
80874    /**
80875     * @private
80876     * @param {Object} decl style declaration for cache
80877     * @param {String} decl.fontFamily fontFamily
80878     * @param {String} decl.fontStyle fontStyle
80879     * @param {String} decl.fontWeight fontWeight
80880     * @return {Object} reference to cache
80881     */
80882    getFontCache: function(decl) {
80883      var fontFamily = decl.fontFamily.toLowerCase();
80884      if (!fabric.charWidthsCache[fontFamily]) {
80885        fabric.charWidthsCache[fontFamily] = { };
80886      }
80887      var cache = fabric.charWidthsCache[fontFamily],
80888          cacheProp = decl.fontStyle.toLowerCase() + '_' + (decl.fontWeight + '').toLowerCase();
80889      if (!cache[cacheProp]) {
80890        cache[cacheProp] = { };
80891      }
80892      return cache[cacheProp];
80893    },
80894
80895    /**
80896     * measure and return the width of a single character.
80897     * possibly overridden to accommodate different measure logic or
80898     * to hook some external lib for character measurement
80899     * @private
80900     * @param {String} _char, char to be measured
80901     * @param {Object} charStyle style of char to be measured
80902     * @param {String} [previousChar] previous char
80903     * @param {Object} [prevCharStyle] style of previous char
80904     */
80905    _measureChar: function(_char, charStyle, previousChar, prevCharStyle) {
80906      // first i try to return from cache
80907      var fontCache = this.getFontCache(charStyle), fontDeclaration = this._getFontDeclaration(charStyle),
80908          previousFontDeclaration = this._getFontDeclaration(prevCharStyle), couple = previousChar + _char,
80909          stylesAreEqual = fontDeclaration === previousFontDeclaration, width, coupleWidth, previousWidth,
80910          fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE, kernedWidth;
80911
80912      if (previousChar && fontCache[previousChar] !== undefined) {
80913        previousWidth = fontCache[previousChar];
80914      }
80915      if (fontCache[_char] !== undefined) {
80916        kernedWidth = width = fontCache[_char];
80917      }
80918      if (stylesAreEqual && fontCache[couple] !== undefined) {
80919        coupleWidth = fontCache[couple];
80920        kernedWidth = coupleWidth - previousWidth;
80921      }
80922      if (width === undefined || previousWidth === undefined || coupleWidth === undefined) {
80923        var ctx = this.getMeasuringContext();
80924        // send a TRUE to specify measuring font size CACHE_FONT_SIZE
80925        this._setTextStyles(ctx, charStyle, true);
80926      }
80927      if (width === undefined) {
80928        kernedWidth = width = ctx.measureText(_char).width;
80929        fontCache[_char] = width;
80930      }
80931      if (previousWidth === undefined && stylesAreEqual && previousChar) {
80932        previousWidth = ctx.measureText(previousChar).width;
80933        fontCache[previousChar] = previousWidth;
80934      }
80935      if (stylesAreEqual && coupleWidth === undefined) {
80936        // we can measure the kerning couple and subtract the width of the previous character
80937        coupleWidth = ctx.measureText(couple).width;
80938        fontCache[couple] = coupleWidth;
80939        kernedWidth = coupleWidth - previousWidth;
80940      }
80941      return { width: width * fontMultiplier, kernedWidth: kernedWidth * fontMultiplier };
80942    },
80943
80944    /**
80945     * Computes height of character at given position
80946     * @param {Number} line the line index number
80947     * @param {Number} _char the character index number
80948     * @return {Number} fontSize of the character
80949     */
80950    getHeightOfChar: function(line, _char) {
80951      return this.getValueOfPropertyAt(line, _char, 'fontSize');
80952    },
80953
80954    /**
80955     * measure a text line measuring all characters.
80956     * @param {Number} lineIndex line number
80957     * @return {Number} Line width
80958     */
80959    measureLine: function(lineIndex) {
80960      var lineInfo = this._measureLine(lineIndex);
80961      if (this.charSpacing !== 0) {
80962        lineInfo.width -= this._getWidthOfCharSpacing();
80963      }
80964      if (lineInfo.width < 0) {
80965        lineInfo.width = 0;
80966      }
80967      return lineInfo;
80968    },
80969
80970    /**
80971     * measure every grapheme of a line, populating __charBounds
80972     * @param {Number} lineIndex
80973     * @return {Object} object.width total width of characters
80974     * @return {Object} object.widthOfSpaces length of chars that match this._reSpacesAndTabs
80975     */
80976    _measureLine: function(lineIndex) {
80977      var width = 0, i, grapheme, line = this._textLines[lineIndex], prevGrapheme,
80978          graphemeInfo, numOfSpaces = 0, lineBounds = new Array(line.length),
80979          positionInPath = 0, startingPoint, totalPathLength, path = this.path,
80980          reverse = this.pathSide === 'right';
80981
80982      this.__charBounds[lineIndex] = lineBounds;
80983      for (i = 0; i < line.length; i++) {
80984        grapheme = line[i];
80985        graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme);
80986        lineBounds[i] = graphemeInfo;
80987        width += graphemeInfo.kernedWidth;
80988        prevGrapheme = grapheme;
80989      }
80990      // this latest bound box represent the last character of the line
80991      // to simplify cursor handling in interactive mode.
80992      lineBounds[i] = {
80993        left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0,
80994        width: 0,
80995        kernedWidth: 0,
80996        height: this.fontSize
80997      };
80998      if (path) {
80999        totalPathLength = path.segmentsInfo[path.segmentsInfo.length - 1].length;
81000        startingPoint = fabric.util.getPointOnPath(path.path, 0, path.segmentsInfo);
81001        startingPoint.x += path.pathOffset.x;
81002        startingPoint.y += path.pathOffset.y;
81003        switch (this.textAlign) {
81004          case 'left':
81005            positionInPath = reverse ? (totalPathLength - width) : 0;
81006            break;
81007          case 'center':
81008            positionInPath = (totalPathLength - width) / 2;
81009            break;
81010          case 'right':
81011            positionInPath = reverse ? 0 : (totalPathLength - width);
81012            break;
81013          //todo - add support for justify
81014        }
81015        positionInPath += this.pathStartOffset * (reverse ? -1 : 1);
81016        for (i = reverse ? line.length - 1 : 0;
81017          reverse ? i >= 0 : i < line.length;
81018          reverse ? i-- : i++) {
81019          graphemeInfo = lineBounds[i];
81020          if (positionInPath > totalPathLength) {
81021            positionInPath %= totalPathLength;
81022          }
81023          else if (positionInPath < 0) {
81024            positionInPath += totalPathLength;
81025          }
81026          // it would probably much faster to send all the grapheme position for a line
81027          // and calculate path position/angle at once.
81028          this._setGraphemeOnPath(positionInPath, graphemeInfo, startingPoint);
81029          positionInPath += graphemeInfo.kernedWidth;
81030        }
81031      }
81032      return { width: width, numOfSpaces: numOfSpaces };
81033    },
81034
81035    /**
81036     * Calculate the angle  and the left,top position of the char that follow a path.
81037     * It appends it to graphemeInfo to be reused later at rendering
81038     * @private
81039     * @param {Number} positionInPath to be measured
81040     * @param {Object} graphemeInfo current grapheme box information
81041     * @param {Object} startingPoint position of the point
81042     */
81043    _setGraphemeOnPath: function(positionInPath, graphemeInfo, startingPoint) {
81044      var centerPosition = positionInPath + graphemeInfo.kernedWidth / 2,
81045          path = this.path;
81046
81047      // we are at currentPositionOnPath. we want to know what point on the path is.
81048      var info = fabric.util.getPointOnPath(path.path, centerPosition, path.segmentsInfo);
81049      graphemeInfo.renderLeft = info.x - startingPoint.x;
81050      graphemeInfo.renderTop = info.y - startingPoint.y;
81051      graphemeInfo.angle = info.angle + (this.pathSide ===  'right' ? Math.PI : 0);
81052    },
81053
81054    /**
81055     * Measure and return the info of a single grapheme.
81056     * needs the the info of previous graphemes already filled
81057     * @private
81058     * @param {String} grapheme to be measured
81059     * @param {Number} lineIndex index of the line where the char is
81060     * @param {Number} charIndex position in the line
81061     * @param {String} [prevGrapheme] character preceding the one to be measured
81062     */
81063    _getGraphemeBox: function(grapheme, lineIndex, charIndex, prevGrapheme, skipLeft) {
81064      var style = this.getCompleteStyleDeclaration(lineIndex, charIndex),
81065          prevStyle = prevGrapheme ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1) : { },
81066          info = this._measureChar(grapheme, style, prevGrapheme, prevStyle),
81067          kernedWidth = info.kernedWidth,
81068          width = info.width, charSpacing;
81069
81070      if (this.charSpacing !== 0) {
81071        charSpacing = this._getWidthOfCharSpacing();
81072        width += charSpacing;
81073        kernedWidth += charSpacing;
81074      }
81075
81076      var box = {
81077        width: width,
81078        left: 0,
81079        height: style.fontSize,
81080        kernedWidth: kernedWidth,
81081        deltaY: style.deltaY,
81082      };
81083      if (charIndex > 0 && !skipLeft) {
81084        var previousBox = this.__charBounds[lineIndex][charIndex - 1];
81085        box.left = previousBox.left + previousBox.width + info.kernedWidth - info.width;
81086      }
81087      return box;
81088    },
81089
81090    /**
81091     * Calculate height of line at 'lineIndex'
81092     * @param {Number} lineIndex index of line to calculate
81093     * @return {Number}
81094     */
81095    getHeightOfLine: function(lineIndex) {
81096      if (this.__lineHeights[lineIndex]) {
81097        return this.__lineHeights[lineIndex];
81098      }
81099
81100      var line = this._textLines[lineIndex],
81101          // char 0 is measured before the line cycle because it nneds to char
81102          // emptylines
81103          maxHeight = this.getHeightOfChar(lineIndex, 0);
81104      for (var i = 1, len = line.length; i < len; i++) {
81105        maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight);
81106      }
81107
81108      return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult;
81109    },
81110
81111    /**
81112     * Calculate text box height
81113     */
81114    calcTextHeight: function() {
81115      var lineHeight, height = 0;
81116      for (var i = 0, len = this._textLines.length; i < len; i++) {
81117        lineHeight = this.getHeightOfLine(i);
81118        height += (i === len - 1 ? lineHeight / this.lineHeight : lineHeight);
81119      }
81120      return height;
81121    },
81122
81123    /**
81124     * @private
81125     * @return {Number} Left offset
81126     */
81127    _getLeftOffset: function() {
81128      return this.direction === 'ltr' ? -this.width / 2 : this.width / 2;
81129    },
81130
81131    /**
81132     * @private
81133     * @return {Number} Top offset
81134     */
81135    _getTopOffset: function() {
81136      return -this.height / 2;
81137    },
81138
81139    /**
81140     * @private
81141     * @param {CanvasRenderingContext2D} ctx Context to render on
81142     * @param {String} method Method name ("fillText" or "strokeText")
81143     */
81144    _renderTextCommon: function(ctx, method) {
81145      ctx.save();
81146      var lineHeights = 0, left = this._getLeftOffset(), top = this._getTopOffset();
81147      for (var i = 0, len = this._textLines.length; i < len; i++) {
81148        var heightOfLine = this.getHeightOfLine(i),
81149            maxHeight = heightOfLine / this.lineHeight,
81150            leftOffset = this._getLineLeftOffset(i);
81151        this._renderTextLine(
81152          method,
81153          ctx,
81154          this._textLines[i],
81155          left + leftOffset,
81156          top + lineHeights + maxHeight,
81157          i
81158        );
81159        lineHeights += heightOfLine;
81160      }
81161      ctx.restore();
81162    },
81163
81164    /**
81165     * @private
81166     * @param {CanvasRenderingContext2D} ctx Context to render on
81167     */
81168    _renderTextFill: function(ctx) {
81169      if (!this.fill && !this.styleHas('fill')) {
81170        return;
81171      }
81172
81173      this._renderTextCommon(ctx, 'fillText');
81174    },
81175
81176    /**
81177     * @private
81178     * @param {CanvasRenderingContext2D} ctx Context to render on
81179     */
81180    _renderTextStroke: function(ctx) {
81181      if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {
81182        return;
81183      }
81184
81185      if (this.shadow && !this.shadow.affectStroke) {
81186        this._removeShadow(ctx);
81187      }
81188
81189      ctx.save();
81190      this._setLineDash(ctx, this.strokeDashArray);
81191      ctx.beginPath();
81192      this._renderTextCommon(ctx, 'strokeText');
81193      ctx.closePath();
81194      ctx.restore();
81195    },
81196
81197    /**
81198     * @private
81199     * @param {String} method fillText or strokeText.
81200     * @param {CanvasRenderingContext2D} ctx Context to render on
81201     * @param {Array} line Content of the line, splitted in an array by grapheme
81202     * @param {Number} left
81203     * @param {Number} top
81204     * @param {Number} lineIndex
81205     */
81206    _renderChars: function(method, ctx, line, left, top, lineIndex) {
81207      // set proper line offset
81208      var lineHeight = this.getHeightOfLine(lineIndex),
81209          isJustify = this.textAlign.indexOf('justify') !== -1,
81210          actualStyle,
81211          nextStyle,
81212          charsToRender = '',
81213          charBox,
81214          boxWidth = 0,
81215          timeToRender,
81216          path = this.path,
81217          shortCut = !isJustify && this.charSpacing === 0 && this.isEmptyStyles(lineIndex) && !path,
81218          isLtr = this.direction === 'ltr', sign = this.direction === 'ltr' ? 1 : -1,
81219          drawingLeft;
81220
81221      ctx.save();
81222      top -= lineHeight * this._fontSizeFraction / this.lineHeight;
81223      if (shortCut) {
81224        // render all the line in one pass without checking
81225        // drawingLeft = isLtr ? left : left - this.getLineWidth(lineIndex);
81226        ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl');
81227        ctx.direction = isLtr ? 'ltr' : 'rtl';
81228        ctx.textAlign = isLtr ? 'left' : 'right';
81229        this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top, lineHeight);
81230        ctx.restore();
81231        return;
81232      }
81233      for (var i = 0, len = line.length - 1; i <= len; i++) {
81234        timeToRender = i === len || this.charSpacing || path;
81235        charsToRender += line[i];
81236        charBox = this.__charBounds[lineIndex][i];
81237        if (boxWidth === 0) {
81238          left += sign * (charBox.kernedWidth - charBox.width);
81239          boxWidth += charBox.width;
81240        }
81241        else {
81242          boxWidth += charBox.kernedWidth;
81243        }
81244        if (isJustify && !timeToRender) {
81245          if (this._reSpaceAndTab.test(line[i])) {
81246            timeToRender = true;
81247          }
81248        }
81249        if (!timeToRender) {
81250          // if we have charSpacing, we render char by char
81251          actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);
81252          nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);
81253          timeToRender = this._hasStyleChanged(actualStyle, nextStyle);
81254        }
81255        if (timeToRender) {
81256          if (path) {
81257            ctx.save();
81258            ctx.translate(charBox.renderLeft, charBox.renderTop);
81259            ctx.rotate(charBox.angle);
81260            this._renderChar(method, ctx, lineIndex, i, charsToRender, -boxWidth / 2, 0, lineHeight);
81261            ctx.restore();
81262          }
81263          else {
81264            drawingLeft = left;
81265            ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl');
81266            ctx.direction = isLtr ? 'ltr' : 'rtl';
81267            ctx.textAlign = isLtr ? 'left' : 'right';
81268            this._renderChar(method, ctx, lineIndex, i, charsToRender, drawingLeft, top, lineHeight);
81269          }
81270          charsToRender = '';
81271          actualStyle = nextStyle;
81272          left += sign * boxWidth;
81273          boxWidth = 0;
81274        }
81275      }
81276      ctx.restore();
81277    },
81278
81279    /**
81280     * This function try to patch the missing gradientTransform on canvas gradients.
81281     * transforming a context to transform the gradient, is going to transform the stroke too.
81282     * we want to transform the gradient but not the stroke operation, so we create
81283     * a transformed gradient on a pattern and then we use the pattern instead of the gradient.
81284     * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size
81285     * is limited.
81286     * @private
81287     * @param {fabric.Gradient} filler a fabric gradient instance
81288     * @return {CanvasPattern} a pattern to use as fill/stroke style
81289     */
81290    _applyPatternGradientTransformText: function(filler) {
81291      var pCanvas = fabric.util.createCanvasElement(), pCtx,
81292          // TODO: verify compatibility with strokeUniform
81293          width = this.width + this.strokeWidth, height = this.height + this.strokeWidth;
81294      pCanvas.width = width;
81295      pCanvas.height = height;
81296      pCtx = pCanvas.getContext('2d');
81297      pCtx.beginPath(); pCtx.moveTo(0, 0); pCtx.lineTo(width, 0); pCtx.lineTo(width, height);
81298      pCtx.lineTo(0, height); pCtx.closePath();
81299      pCtx.translate(width / 2, height / 2);
81300      pCtx.fillStyle = filler.toLive(pCtx);
81301      this._applyPatternGradientTransform(pCtx, filler);
81302      pCtx.fill();
81303      return pCtx.createPattern(pCanvas, 'no-repeat');
81304    },
81305
81306    handleFiller: function(ctx, property, filler) {
81307      var offsetX, offsetY;
81308      if (filler.toLive) {
81309        if (filler.gradientUnits === 'percentage' || filler.gradientTransform || filler.patternTransform) {
81310          // need to transform gradient in a pattern.
81311          // this is a slow process. If you are hitting this codepath, and the object
81312          // is not using caching, you should consider switching it on.
81313          // we need a canvas as big as the current object caching canvas.
81314          offsetX = -this.width / 2;
81315          offsetY = -this.height / 2;
81316          ctx.translate(offsetX, offsetY);
81317          ctx[property] = this._applyPatternGradientTransformText(filler);
81318          return { offsetX: offsetX, offsetY: offsetY };
81319        }
81320        else {
81321          // is a simple gradient or pattern
81322          ctx[property] = filler.toLive(ctx, this);
81323          return this._applyPatternGradientTransform(ctx, filler);
81324        }
81325      }
81326      else {
81327        // is a color
81328        ctx[property] = filler;
81329      }
81330      return { offsetX: 0, offsetY: 0 };
81331    },
81332
81333    _setStrokeStyles: function(ctx, decl) {
81334      ctx.lineWidth = decl.strokeWidth;
81335      ctx.lineCap = this.strokeLineCap;
81336      ctx.lineDashOffset = this.strokeDashOffset;
81337      ctx.lineJoin = this.strokeLineJoin;
81338      ctx.miterLimit = this.strokeMiterLimit;
81339      return this.handleFiller(ctx, 'strokeStyle', decl.stroke);
81340    },
81341
81342    _setFillStyles: function(ctx, decl) {
81343      return this.handleFiller(ctx, 'fillStyle', decl.fill);
81344    },
81345
81346    /**
81347     * @private
81348     * @param {String} method
81349     * @param {CanvasRenderingContext2D} ctx Context to render on
81350     * @param {Number} lineIndex
81351     * @param {Number} charIndex
81352     * @param {String} _char
81353     * @param {Number} left Left coordinate
81354     * @param {Number} top Top coordinate
81355     * @param {Number} lineHeight Height of the line
81356     */
81357    _renderChar: function(method, ctx, lineIndex, charIndex, _char, left, top) {
81358      var decl = this._getStyleDeclaration(lineIndex, charIndex),
81359          fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex),
81360          shouldFill = method === 'fillText' && fullDecl.fill,
81361          shouldStroke = method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth,
81362          fillOffsets, strokeOffsets;
81363
81364      if (!shouldStroke && !shouldFill) {
81365        return;
81366      }
81367      ctx.save();
81368
81369      shouldFill && (fillOffsets = this._setFillStyles(ctx, fullDecl));
81370      shouldStroke && (strokeOffsets = this._setStrokeStyles(ctx, fullDecl));
81371
81372      ctx.font = this._getFontDeclaration(fullDecl);
81373
81374
81375      if (decl && decl.textBackgroundColor) {
81376        this._removeShadow(ctx);
81377      }
81378      if (decl && decl.deltaY) {
81379        top += decl.deltaY;
81380      }
81381      shouldFill && ctx.fillText(_char, left - fillOffsets.offsetX, top - fillOffsets.offsetY);
81382      shouldStroke && ctx.strokeText(_char, left - strokeOffsets.offsetX, top - strokeOffsets.offsetY);
81383      ctx.restore();
81384    },
81385
81386    /**
81387     * Turns the character into a 'superior figure' (i.e. 'superscript')
81388     * @param {Number} start selection start
81389     * @param {Number} end selection end
81390     * @returns {fabric.Text} thisArg
81391     * @chainable
81392     */
81393    setSuperscript: function(start, end) {
81394      return this._setScript(start, end, this.superscript);
81395    },
81396
81397    /**
81398     * Turns the character into an 'inferior figure' (i.e. 'subscript')
81399     * @param {Number} start selection start
81400     * @param {Number} end selection end
81401     * @returns {fabric.Text} thisArg
81402     * @chainable
81403     */
81404    setSubscript: function(start, end) {
81405      return this._setScript(start, end, this.subscript);
81406    },
81407
81408    /**
81409     * Applies 'schema' at given position
81410     * @private
81411     * @param {Number} start selection start
81412     * @param {Number} end selection end
81413     * @param {Number} schema
81414     * @returns {fabric.Text} thisArg
81415     * @chainable
81416     */
81417    _setScript: function(start, end, schema) {
81418      var loc = this.get2DCursorLocation(start, true),
81419          fontSize = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'fontSize'),
81420          dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'),
81421          style = { fontSize: fontSize * schema.size, deltaY: dy + fontSize * schema.baseline };
81422      this.setSelectionStyles(style, start, end);
81423      return this;
81424    },
81425
81426    /**
81427     * @private
81428     * @param {Object} prevStyle
81429     * @param {Object} thisStyle
81430     */
81431    _hasStyleChanged: function(prevStyle, thisStyle) {
81432      return prevStyle.fill !== thisStyle.fill ||
81433              prevStyle.stroke !== thisStyle.stroke ||
81434              prevStyle.strokeWidth !== thisStyle.strokeWidth ||
81435              prevStyle.fontSize !== thisStyle.fontSize ||
81436              prevStyle.fontFamily !== thisStyle.fontFamily ||
81437              prevStyle.fontWeight !== thisStyle.fontWeight ||
81438              prevStyle.fontStyle !== thisStyle.fontStyle ||
81439              prevStyle.deltaY !== thisStyle.deltaY;
81440    },
81441
81442    /**
81443     * @private
81444     * @param {Object} prevStyle
81445     * @param {Object} thisStyle
81446     */
81447    _hasStyleChangedForSvg: function(prevStyle, thisStyle) {
81448      return this._hasStyleChanged(prevStyle, thisStyle) ||
81449        prevStyle.overline !== thisStyle.overline ||
81450        prevStyle.underline !== thisStyle.underline ||
81451        prevStyle.linethrough !== thisStyle.linethrough;
81452    },
81453
81454    /**
81455     * @private
81456     * @param {Number} lineIndex index text line
81457     * @return {Number} Line left offset
81458     */
81459    _getLineLeftOffset: function(lineIndex) {
81460      var lineWidth = this.getLineWidth(lineIndex),
81461          lineDiff = this.width - lineWidth, textAlign = this.textAlign, direction = this.direction,
81462          isEndOfWrapping, leftOffset = 0, isEndOfWrapping = this.isEndOfWrapping(lineIndex);
81463      if (textAlign === 'justify'
81464        || (textAlign === 'justify-center' && !isEndOfWrapping)
81465        || (textAlign === 'justify-right' && !isEndOfWrapping)
81466        || (textAlign === 'justify-left' && !isEndOfWrapping)
81467      ) {
81468        return 0;
81469      }
81470      if (textAlign === 'center') {
81471        leftOffset = lineDiff / 2;
81472      }
81473      if (textAlign === 'right') {
81474        leftOffset = lineDiff;
81475      }
81476      if (textAlign === 'justify-center') {
81477        leftOffset = lineDiff / 2;
81478      }
81479      if (textAlign === 'justify-right') {
81480        leftOffset = lineDiff;
81481      }
81482      if (direction === 'rtl') {
81483        leftOffset -= lineDiff;
81484      }
81485      return leftOffset;
81486    },
81487
81488    /**
81489     * @private
81490     */
81491    _clearCache: function() {
81492      this.__lineWidths = [];
81493      this.__lineHeights = [];
81494      this.__charBounds = [];
81495    },
81496
81497    /**
81498     * @private
81499     */
81500    _shouldClearDimensionCache: function() {
81501      var shouldClear = this._forceClearCache;
81502      shouldClear || (shouldClear = this.hasStateChanged('_dimensionAffectingProps'));
81503      if (shouldClear) {
81504        this.dirty = true;
81505        this._forceClearCache = false;
81506      }
81507      return shouldClear;
81508    },
81509
81510    /**
81511     * Measure a single line given its index. Used to calculate the initial
81512     * text bounding box. The values are calculated and stored in __lineWidths cache.
81513     * @private
81514     * @param {Number} lineIndex line number
81515     * @return {Number} Line width
81516     */
81517    getLineWidth: function(lineIndex) {
81518      if (this.__lineWidths[lineIndex]) {
81519        return this.__lineWidths[lineIndex];
81520      }
81521
81522      var width, line = this._textLines[lineIndex], lineInfo;
81523
81524      if (line === '') {
81525        width = 0;
81526      }
81527      else {
81528        lineInfo = this.measureLine(lineIndex);
81529        width = lineInfo.width;
81530      }
81531      this.__lineWidths[lineIndex] = width;
81532      return width;
81533    },
81534
81535    _getWidthOfCharSpacing: function() {
81536      if (this.charSpacing !== 0) {
81537        return this.fontSize * this.charSpacing / 1000;
81538      }
81539      return 0;
81540    },
81541
81542    /**
81543     * Retrieves the value of property at given character position
81544     * @param {Number} lineIndex the line number
81545     * @param {Number} charIndex the character number
81546     * @param {String} property the property name
81547     * @returns the value of 'property'
81548     */
81549    getValueOfPropertyAt: function(lineIndex, charIndex, property) {
81550      var charStyle = this._getStyleDeclaration(lineIndex, charIndex);
81551      if (charStyle && typeof charStyle[property] !== 'undefined') {
81552        return charStyle[property];
81553      }
81554      return this[property];
81555    },
81556
81557    /**
81558     * @private
81559     * @param {CanvasRenderingContext2D} ctx Context to render on
81560     */
81561    _renderTextDecoration: function(ctx, type) {
81562      if (!this[type] && !this.styleHas(type)) {
81563        return;
81564      }
81565      var heightOfLine, size, _size,
81566          lineLeftOffset, dy, _dy,
81567          line, lastDecoration,
81568          leftOffset = this._getLeftOffset(),
81569          topOffset = this._getTopOffset(), top,
81570          boxStart, boxWidth, charBox, currentDecoration,
81571          maxHeight, currentFill, lastFill, path = this.path,
81572          charSpacing = this._getWidthOfCharSpacing(),
81573          offsetY = this.offsets[type];
81574
81575      for (var i = 0, len = this._textLines.length; i < len; i++) {
81576        heightOfLine = this.getHeightOfLine(i);
81577        if (!this[type] && !this.styleHas(type, i)) {
81578          topOffset += heightOfLine;
81579          continue;
81580        }
81581        line = this._textLines[i];
81582        maxHeight = heightOfLine / this.lineHeight;
81583        lineLeftOffset = this._getLineLeftOffset(i);
81584        boxStart = 0;
81585        boxWidth = 0;
81586        lastDecoration = this.getValueOfPropertyAt(i, 0, type);
81587        lastFill = this.getValueOfPropertyAt(i, 0, 'fill');
81588        top = topOffset + maxHeight * (1 - this._fontSizeFraction);
81589        size = this.getHeightOfChar(i, 0);
81590        dy = this.getValueOfPropertyAt(i, 0, 'deltaY');
81591        for (var j = 0, jlen = line.length; j < jlen; j++) {
81592          charBox = this.__charBounds[i][j];
81593          currentDecoration = this.getValueOfPropertyAt(i, j, type);
81594          currentFill = this.getValueOfPropertyAt(i, j, 'fill');
81595          _size = this.getHeightOfChar(i, j);
81596          _dy = this.getValueOfPropertyAt(i, j, 'deltaY');
81597          if (path && currentDecoration && currentFill) {
81598            ctx.save();
81599            ctx.fillStyle = lastFill;
81600            ctx.translate(charBox.renderLeft, charBox.renderTop);
81601            ctx.rotate(charBox.angle);
81602            ctx.fillRect(
81603              -charBox.kernedWidth / 2,
81604              offsetY * _size + _dy,
81605              charBox.kernedWidth,
81606              this.fontSize / 15
81607            );
81608            ctx.restore();
81609          }
81610          else if (
81611            (currentDecoration !== lastDecoration || currentFill !== lastFill || _size !== size || _dy !== dy)
81612            && boxWidth > 0
81613          ) {
81614            var drawStart = leftOffset + lineLeftOffset + boxStart;
81615            if (this.direction === 'rtl') {
81616              drawStart = this.width - drawStart - boxWidth;
81617            }
81618            if (lastDecoration && lastFill) {
81619              ctx.fillStyle = lastFill;
81620              ctx.fillRect(
81621                drawStart,
81622                top + offsetY * size + dy,
81623                boxWidth,
81624                this.fontSize / 15
81625              );
81626            }
81627            boxStart = charBox.left;
81628            boxWidth = charBox.width;
81629            lastDecoration = currentDecoration;
81630            lastFill = currentFill;
81631            size = _size;
81632            dy = _dy;
81633          }
81634          else {
81635            boxWidth += charBox.kernedWidth;
81636          }
81637        }
81638        var drawStart = leftOffset + lineLeftOffset + boxStart;
81639        if (this.direction === 'rtl') {
81640          drawStart = this.width - drawStart - boxWidth;
81641        }
81642        ctx.fillStyle = currentFill;
81643        currentDecoration && currentFill && ctx.fillRect(
81644          drawStart,
81645          top + offsetY * size + dy,
81646          boxWidth - charSpacing,
81647          this.fontSize / 15
81648        );
81649        topOffset += heightOfLine;
81650      }
81651      // if there is text background color no
81652      // other shadows should be casted
81653      this._removeShadow(ctx);
81654    },
81655
81656    /**
81657     * return font declaration string for canvas context
81658     * @param {Object} [styleObject] object
81659     * @returns {String} font declaration formatted for canvas context.
81660     */
81661    _getFontDeclaration: function(styleObject, forMeasuring) {
81662      var style = styleObject || this, family = this.fontFamily,
81663          fontIsGeneric = fabric.Text.genericFonts.indexOf(family.toLowerCase()) > -1;
81664      var fontFamily = family === undefined ||
81665      family.indexOf('\'') > -1 || family.indexOf(',') > -1 ||
81666      family.indexOf('"') > -1 || fontIsGeneric
81667        ? style.fontFamily : '"' + style.fontFamily + '"';
81668      return [
81669        // node-canvas needs "weight style", while browsers need "style weight"
81670        // verify if this can be fixed in JSDOM
81671        (fabric.isLikelyNode ? style.fontWeight : style.fontStyle),
81672        (fabric.isLikelyNode ? style.fontStyle : style.fontWeight),
81673        forMeasuring ? this.CACHE_FONT_SIZE + 'px' : style.fontSize + 'px',
81674        fontFamily
81675      ].join(' ');
81676    },
81677
81678    /**
81679     * Renders text instance on a specified context
81680     * @param {CanvasRenderingContext2D} ctx Context to render on
81681     */
81682    render: function(ctx) {
81683      // do not render if object is not visible
81684      if (!this.visible) {
81685        return;
81686      }
81687      if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {
81688        return;
81689      }
81690      if (this._shouldClearDimensionCache()) {
81691        this.initDimensions();
81692      }
81693      this.callSuper('render', ctx);
81694    },
81695
81696    /**
81697     * Returns the text as an array of lines.
81698     * @param {String} text text to split
81699     * @returns {Array} Lines in the text
81700     */
81701    _splitTextIntoLines: function(text) {
81702      var lines = text.split(this._reNewline),
81703          newLines = new Array(lines.length),
81704          newLine = ['\n'],
81705          newText = [];
81706      for (var i = 0; i < lines.length; i++) {
81707        newLines[i] = fabric.util.string.graphemeSplit(lines[i]);
81708        newText = newText.concat(newLines[i], newLine);
81709      }
81710      newText.pop();
81711      return { _unwrappedLines: newLines, lines: lines, graphemeText: newText, graphemeLines: newLines };
81712    },
81713
81714    /**
81715     * Returns object representation of an instance
81716     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
81717     * @return {Object} Object representation of an instance
81718     */
81719    toObject: function(propertiesToInclude) {
81720      var allProperties = additionalProps.concat(propertiesToInclude);
81721      var obj = this.callSuper('toObject', allProperties);
81722      // styles will be overridden with a properly cloned structure
81723      obj.styles = clone(this.styles, true);
81724      if (obj.path) {
81725        obj.path = this.path.toObject();
81726      }
81727      return obj;
81728    },
81729
81730    /**
81731     * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.
81732     * @param {String|Object} key Property name or object (if object, iterate over the object properties)
81733     * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)
81734     * @return {fabric.Object} thisArg
81735     * @chainable
81736     */
81737    set: function(key, value) {
81738      this.callSuper('set', key, value);
81739      var needsDims = false;
81740      var isAddingPath = false;
81741      if (typeof key === 'object') {
81742        for (var _key in key) {
81743          if (_key === 'path') {
81744            this.setPathInfo();
81745          }
81746          needsDims = needsDims || this._dimensionAffectingProps.indexOf(_key) !== -1;
81747          isAddingPath = isAddingPath || _key === 'path';
81748        }
81749      }
81750      else {
81751        needsDims = this._dimensionAffectingProps.indexOf(key) !== -1;
81752        isAddingPath = key === 'path';
81753      }
81754      if (isAddingPath) {
81755        this.setPathInfo();
81756      }
81757      if (needsDims) {
81758        this.initDimensions();
81759        this.setCoords();
81760      }
81761      return this;
81762    },
81763
81764    /**
81765     * Returns complexity of an instance
81766     * @return {Number} complexity
81767     */
81768    complexity: function() {
81769      return 1;
81770    }
81771  });
81772
81773  /* _FROM_SVG_START_ */
81774  /**
81775   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement})
81776   * @static
81777   * @memberOf fabric.Text
81778   * @see: http://www.w3.org/TR/SVG/text.html#TextElement
81779   */
81780  fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(
81781    'x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor'.split(' '));
81782
81783  /**
81784   * Default SVG font size
81785   * @static
81786   * @memberOf fabric.Text
81787   */
81788  fabric.Text.DEFAULT_SVG_FONT_SIZE = 16;
81789
81790  /**
81791   * Returns fabric.Text instance from an SVG element (<b>not yet implemented</b>)
81792   * @static
81793   * @memberOf fabric.Text
81794   * @param {SVGElement} element Element to parse
81795   * @param {Function} callback callback function invoked after parsing
81796   * @param {Object} [options] Options object
81797   */
81798  fabric.Text.fromElement = function(element, callback, options) {
81799    if (!element) {
81800      return callback(null);
81801    }
81802
81803    var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES),
81804        parsedAnchor = parsedAttributes.textAnchor || 'left';
81805    options = fabric.util.object.extend((options ? clone(options) : { }), parsedAttributes);
81806
81807    options.top = options.top || 0;
81808    options.left = options.left || 0;
81809    if (parsedAttributes.textDecoration) {
81810      var textDecoration = parsedAttributes.textDecoration;
81811      if (textDecoration.indexOf('underline') !== -1) {
81812        options.underline = true;
81813      }
81814      if (textDecoration.indexOf('overline') !== -1) {
81815        options.overline = true;
81816      }
81817      if (textDecoration.indexOf('line-through') !== -1) {
81818        options.linethrough = true;
81819      }
81820      delete options.textDecoration;
81821    }
81822    if ('dx' in parsedAttributes) {
81823      options.left += parsedAttributes.dx;
81824    }
81825    if ('dy' in parsedAttributes) {
81826      options.top += parsedAttributes.dy;
81827    }
81828    if (!('fontSize' in options)) {
81829      options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;
81830    }
81831
81832    var textContent = '';
81833
81834    // The XML is not properly parsed in IE9 so a workaround to get
81835    // textContent is through firstChild.data. Another workaround would be
81836    // to convert XML loaded from a file to be converted using DOMParser (same way loadSVGFromString() does)
81837    if (!('textContent' in element)) {
81838      if ('firstChild' in element && element.firstChild !== null) {
81839        if ('data' in element.firstChild && element.firstChild.data !== null) {
81840          textContent = element.firstChild.data;
81841        }
81842      }
81843    }
81844    else {
81845      textContent = element.textContent;
81846    }
81847
81848    textContent = textContent.replace(/^\s+|\s+$|\n+/g, '').replace(/\s+/g, ' ');
81849    var originalStrokeWidth = options.strokeWidth;
81850    options.strokeWidth = 0;
81851
81852    var text = new fabric.Text(textContent, options),
81853        textHeightScaleFactor = text.getScaledHeight() / text.height,
81854        lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height,
81855        scaledDiff = lineHeightDiff * textHeightScaleFactor,
81856        textHeight = text.getScaledHeight() + scaledDiff,
81857        offX = 0;
81858    /*
81859      Adjust positioning:
81860        x/y attributes in SVG correspond to the bottom-left corner of text bounding box
81861        fabric output by default at top, left.
81862    */
81863    if (parsedAnchor === 'center') {
81864      offX = text.getScaledWidth() / 2;
81865    }
81866    if (parsedAnchor === 'right') {
81867      offX = text.getScaledWidth();
81868    }
81869    text.set({
81870      left: text.left - offX,
81871      top: text.top - (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) / text.lineHeight,
81872      strokeWidth: typeof originalStrokeWidth !== 'undefined' ? originalStrokeWidth : 1,
81873    });
81874    callback(text);
81875  };
81876  /* _FROM_SVG_END_ */
81877
81878  /**
81879   * Returns fabric.Text instance from an object representation
81880   * @static
81881   * @memberOf fabric.Text
81882   * @param {Object} object plain js Object to create an instance from
81883   * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created
81884   */
81885  fabric.Text.fromObject = function(object, callback) {
81886    var objectCopy = clone(object), path = object.path;
81887    delete objectCopy.path;
81888    return fabric.Object._fromObject('Text', objectCopy, function(textInstance) {
81889      if (path) {
81890        fabric.Object._fromObject('Path', path, function(pathInstance) {
81891          textInstance.set('path', pathInstance);
81892          callback(textInstance);
81893        }, 'path');
81894      }
81895      else {
81896        callback(textInstance);
81897      }
81898    }, 'text');
81899  };
81900
81901  fabric.Text.genericFonts = ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace'];
81902
81903  fabric.util.createAccessors && fabric.util.createAccessors(fabric.Text);
81904
81905})( true ? exports : 
81905this
vendor: 110,326 bytes, lines 81905-85368
81905);
81906
81907
81908(function() {
81909  fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ {
81910    /**
81911     * Returns true if object has no styling or no styling in a line
81912     * @param {Number} lineIndex , lineIndex is on wrapped lines.
81913     * @return {Boolean}
81914     */
81915    isEmptyStyles: function(lineIndex) {
81916      if (!this.styles) {
81917        return true;
81918      }
81919      if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {
81920        return true;
81921      }
81922      var obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] };
81923      for (var p1 in obj) {
81924        for (var p2 in obj[p1]) {
81925          // eslint-disable-next-line no-unused-vars
81926          for (var p3 in obj[p1][p2]) {
81927            return false;
81928          }
81929        }
81930      }
81931      return true;
81932    },
81933
81934    /**
81935     * Returns true if object has a style property or has it ina specified line
81936     * This function is used to detect if a text will use a particular property or not.
81937     * @param {String} property to check for
81938     * @param {Number} lineIndex to check the style on
81939     * @return {Boolean}
81940     */
81941    styleHas: function(property, lineIndex) {
81942      if (!this.styles || !property || property === '') {
81943        return false;
81944      }
81945      if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {
81946        return false;
81947      }
81948      var obj = typeof lineIndex === 'undefined' ? this.styles : { 0: this.styles[lineIndex] };
81949      // eslint-disable-next-line
81950      for (var p1 in obj) {
81951        // eslint-disable-next-line
81952        for (var p2 in obj[p1]) {
81953          if (typeof obj[p1][p2][property] !== 'undefined') {
81954            return true;
81955          }
81956        }
81957      }
81958      return false;
81959    },
81960
81961    /**
81962     * Check if characters in a text have a value for a property
81963     * whose value matches the textbox's value for that property.  If so,
81964     * the character-level property is deleted.  If the character
81965     * has no other properties, then it is also deleted.  Finally,
81966     * if the line containing that character has no other characters
81967     * then it also is deleted.
81968     *
81969     * @param {string} property The property to compare between characters and text.
81970     */
81971    cleanStyle: function(property) {
81972      if (!this.styles || !property || property === '') {
81973        return false;
81974      }
81975      var obj = this.styles, stylesCount = 0, letterCount, stylePropertyValue,
81976          allStyleObjectPropertiesMatch = true, graphemeCount = 0, styleObject;
81977      // eslint-disable-next-line
81978      for (var p1 in obj) {
81979        letterCount = 0;
81980        // eslint-disable-next-line
81981        for (var p2 in obj[p1]) {
81982          var styleObject = obj[p1][p2],
81983              stylePropertyHasBeenSet = styleObject.hasOwnProperty(property);
81984
81985          stylesCount++;
81986
81987          if (stylePropertyHasBeenSet) {
81988            if (!stylePropertyValue) {
81989              stylePropertyValue = styleObject[property];
81990            }
81991            else if (styleObject[property] !== stylePropertyValue) {
81992              allStyleObjectPropertiesMatch = false;
81993            }
81994
81995            if (styleObject[property] === this[property]) {
81996              delete styleObject[property];
81997            }
81998          }
81999          else {
82000            allStyleObjectPropertiesMatch = false;
82001          }
82002
82003          if (Object.keys(styleObject).length !== 0) {
82004            letterCount++;
82005          }
82006          else {
82007            delete obj[p1][p2];
82008          }
82009        }
82010
82011        if (letterCount === 0) {
82012          delete obj[p1];
82013        }
82014      }
82015      // if every grapheme has the same style set then
82016      // delete those styles and set it on the parent
82017      for (var i = 0; i < this._textLines.length; i++) {
82018        graphemeCount += this._textLines[i].length;
82019      }
82020      if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) {
82021        this[property] = stylePropertyValue;
82022        this.removeStyle(property);
82023      }
82024    },
82025
82026    /**
82027     * Remove a style property or properties from all individual character styles
82028     * in a text object.  Deletes the character style object if it contains no other style
82029     * props.  Deletes a line style object if it contains no other character styles.
82030     *
82031     * @param {String} props The property to remove from character styles.
82032     */
82033    removeStyle: function(property) {
82034      if (!this.styles || !property || property === '') {
82035        return;
82036      }
82037      var obj = this.styles, line, lineNum, charNum;
82038      for (lineNum in obj) {
82039        line = obj[lineNum];
82040        for (charNum in line) {
82041          delete line[charNum][property];
82042          if (Object.keys(line[charNum]).length === 0) {
82043            delete line[charNum];
82044          }
82045        }
82046        if (Object.keys(line).length === 0) {
82047          delete obj[lineNum];
82048        }
82049      }
82050    },
82051
82052    /**
82053     * @private
82054     */
82055    _extendStyles: function(index, styles) {
82056      var loc = this.get2DCursorLocation(index);
82057
82058      if (!this._getLineStyle(loc.lineIndex)) {
82059        this._setLineStyle(loc.lineIndex);
82060      }
82061
82062      if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) {
82063        this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {});
82064      }
82065
82066      fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles);
82067    },
82068
82069    /**
82070     * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)
82071     * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.
82072     * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.
82073     */
82074    get2DCursorLocation: function(selectionStart, skipWrapping) {
82075      if (typeof selectionStart === 'undefined') {
82076        selectionStart = this.selectionStart;
82077      }
82078      var lines = skipWrapping ? this._unwrappedTextLines : this._textLines,
82079          len = lines.length;
82080      for (var i = 0; i < len; i++) {
82081        if (selectionStart <= lines[i].length) {
82082          return {
82083            lineIndex: i,
82084            charIndex: selectionStart
82085          };
82086        }
82087        selectionStart -= lines[i].length + this.missingNewlineOffset(i);
82088      }
82089      return {
82090        lineIndex: i - 1,
82091        charIndex: lines[i - 1].length < selectionStart ? lines[i - 1].length : selectionStart
82092      };
82093    },
82094
82095    /**
82096     * Gets style of a current selection/cursor (at the start position)
82097     * if startIndex or endIndex are not provided, selectionStart or selectionEnd will be used.
82098     * @param {Number} [startIndex] Start index to get styles at
82099     * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1
82100     * @param {Boolean} [complete] get full style or not
82101     * @return {Array} styles an array with one, zero or more Style objects
82102     */
82103    getSelectionStyles: function(startIndex, endIndex, complete) {
82104      if (typeof startIndex === 'undefined') {
82105        startIndex = this.selectionStart || 0;
82106      }
82107      if (typeof endIndex === 'undefined') {
82108        endIndex = this.selectionEnd || startIndex;
82109      }
82110      var styles = [];
82111      for (var i = startIndex; i < endIndex; i++) {
82112        styles.push(this.getStyleAtPosition(i, complete));
82113      }
82114      return styles;
82115    },
82116
82117    /**
82118     * Gets style of a current selection/cursor position
82119     * @param {Number} position  to get styles at
82120     * @param {Boolean} [complete] full style if true
82121     * @return {Object} style Style object at a specified index
82122     * @private
82123     */
82124    getStyleAtPosition: function(position, complete) {
82125      var loc = this.get2DCursorLocation(position),
82126          style = complete ? this.getCompleteStyleDeclaration(loc.lineIndex, loc.charIndex) :
82127            this._getStyleDeclaration(loc.lineIndex, loc.charIndex);
82128      return style || {};
82129    },
82130
82131    /**
82132     * Sets style of a current selection, if no selection exist, do not set anything.
82133     * @param {Object} [styles] Styles object
82134     * @param {Number} [startIndex] Start index to get styles at
82135     * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1
82136     * @return {fabric.IText} thisArg
82137     * @chainable
82138     */
82139    setSelectionStyles: function(styles, startIndex, endIndex) {
82140      if (typeof startIndex === 'undefined') {
82141        startIndex = this.selectionStart || 0;
82142      }
82143      if (typeof endIndex === 'undefined') {
82144        endIndex = this.selectionEnd || startIndex;
82145      }
82146      for (var i = startIndex; i < endIndex; i++) {
82147        this._extendStyles(i, styles);
82148      }
82149      /* not included in _extendStyles to avoid clearing cache more than once */
82150      this._forceClearCache = true;
82151      return this;
82152    },
82153
82154    /**
82155     * get the reference, not a clone, of the style object for a given character
82156     * @param {Number} lineIndex
82157     * @param {Number} charIndex
82158     * @return {Object} style object
82159     */
82160    _getStyleDeclaration: function(lineIndex, charIndex) {
82161      var lineStyle = this.styles && this.styles[lineIndex];
82162      if (!lineStyle) {
82163        return null;
82164      }
82165      return lineStyle[charIndex];
82166    },
82167
82168    /**
82169     * return a new object that contains all the style property for a character
82170     * the object returned is newly created
82171     * @param {Number} lineIndex of the line where the character is
82172     * @param {Number} charIndex position of the character on the line
82173     * @return {Object} style object
82174     */
82175    getCompleteStyleDeclaration: function(lineIndex, charIndex) {
82176      var style = this._getStyleDeclaration(lineIndex, charIndex) || { },
82177          styleObject = { }, prop;
82178      for (var i = 0; i < this._styleProperties.length; i++) {
82179        prop = this._styleProperties[i];
82180        styleObject[prop] = typeof style[prop] === 'undefined' ? this[prop] : style[prop];
82181      }
82182      return styleObject;
82183    },
82184
82185    /**
82186     * @param {Number} lineIndex
82187     * @param {Number} charIndex
82188     * @param {Object} style
82189     * @private
82190     */
82191    _setStyleDeclaration: function(lineIndex, charIndex, style) {
82192      this.styles[lineIndex][charIndex] = style;
82193    },
82194
82195    /**
82196     *
82197     * @param {Number} lineIndex
82198     * @param {Number} charIndex
82199     * @private
82200     */
82201    _deleteStyleDeclaration: function(lineIndex, charIndex) {
82202      delete this.styles[lineIndex][charIndex];
82203    },
82204
82205    /**
82206     * @param {Number} lineIndex
82207     * @return {Boolean} if the line exists or not
82208     * @private
82209     */
82210    _getLineStyle: function(lineIndex) {
82211      return !!this.styles[lineIndex];
82212    },
82213
82214    /**
82215     * Set the line style to an empty object so that is initialized
82216     * @param {Number} lineIndex
82217     * @private
82218     */
82219    _setLineStyle: function(lineIndex) {
82220      this.styles[lineIndex] = {};
82221    },
82222
82223    /**
82224     * @param {Number} lineIndex
82225     * @private
82226     */
82227    _deleteLineStyle: function(lineIndex) {
82228      delete this.styles[lineIndex];
82229    }
82230  });
82231})();
82232
82233
82234(function() {
82235
82236  function parseDecoration(object) {
82237    if (object.textDecoration) {
82238      object.textDecoration.indexOf('underline') > -1 && (object.underline = true);
82239      object.textDecoration.indexOf('line-through') > -1 && (object.linethrough = true);
82240      object.textDecoration.indexOf('overline') > -1 && (object.overline = true);
82241      delete object.textDecoration;
82242    }
82243  }
82244
82245  /**
82246   * IText class (introduced in <b>v1.4</b>) Events are also fired with "text:"
82247   * prefix when observing canvas.
82248   * @class fabric.IText
82249   * @extends fabric.Text
82250   * @mixes fabric.Observable
82251   *
82252   * @fires changed
82253   * @fires selection:changed
82254   * @fires editing:entered
82255   * @fires editing:exited
82256   *
82257   * @return {fabric.IText} thisArg
82258   * @see {@link fabric.IText#initialize} for constructor definition
82259   *
82260   * <p>Supported key combinations:</p>
82261   * <pre>
82262   *   Move cursor:                    left, right, up, down
82263   *   Select character:               shift + left, shift + right
82264   *   Select text vertically:         shift + up, shift + down
82265   *   Move cursor by word:            alt + left, alt + right
82266   *   Select words:                   shift + alt + left, shift + alt + right
82267   *   Move cursor to line start/end:  cmd + left, cmd + right or home, end
82268   *   Select till start/end of line:  cmd + shift + left, cmd + shift + right or shift + home, shift + end
82269   *   Jump to start/end of text:      cmd + up, cmd + down
82270   *   Select till start/end of text:  cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown
82271   *   Delete character:               backspace
82272   *   Delete word:                    alt + backspace
82273   *   Delete line:                    cmd + backspace
82274   *   Forward delete:                 delete
82275   *   Copy text:                      ctrl/cmd + c
82276   *   Paste text:                     ctrl/cmd + v
82277   *   Cut text:                       ctrl/cmd + x
82278   *   Select entire text:             ctrl/cmd + a
82279   *   Quit editing                    tab or esc
82280   * </pre>
82281   *
82282   * <p>Supported mouse/touch combination</p>
82283   * <pre>
82284   *   Position cursor:                click/touch
82285   *   Create selection:               click/touch & drag
82286   *   Create selection:               click & shift + click
82287   *   Select word:                    double click
82288   *   Select line:                    triple click
82289   * </pre>
82290   */
82291  fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, /** @lends fabric.IText.prototype */ {
82292
82293    /**
82294     * Type of an object
82295     * @type String
82296     * @default
82297     */
82298    type: 'i-text',
82299
82300    /**
82301     * Index where text selection starts (or where cursor is when there is no selection)
82302     * @type Number
82303     * @default
82304     */
82305    selectionStart: 0,
82306
82307    /**
82308     * Index where text selection ends
82309     * @type Number
82310     * @default
82311     */
82312    selectionEnd: 0,
82313
82314    /**
82315     * Color of text selection
82316     * @type String
82317     * @default
82318     */
82319    selectionColor: 'rgba(17,119,255,0.3)',
82320
82321    /**
82322     * Indicates whether text is in editing mode
82323     * @type Boolean
82324     * @default
82325     */
82326    isEditing: false,
82327
82328    /**
82329     * Indicates whether a text can be edited
82330     * @type Boolean
82331     * @default
82332     */
82333    editable: true,
82334
82335    /**
82336     * Border color of text object while it's in editing mode
82337     * @type String
82338     * @default
82339     */
82340    editingBorderColor: 'rgba(102,153,255,0.25)',
82341
82342    /**
82343     * Width of cursor (in px)
82344     * @type Number
82345     * @default
82346     */
82347    cursorWidth: 2,
82348
82349    /**
82350     * Color of text cursor color in editing mode.
82351     * if not set (default) will take color from the text.
82352     * if set to a color value that fabric can understand, it will
82353     * be used instead of the color of the text at the current position.
82354     * @type String
82355     * @default
82356     */
82357    cursorColor: '',
82358
82359    /**
82360     * Delay between cursor blink (in ms)
82361     * @type Number
82362     * @default
82363     */
82364    cursorDelay: 1000,
82365
82366    /**
82367     * Duration of cursor fadein (in ms)
82368     * @type Number
82369     * @default
82370     */
82371    cursorDuration: 600,
82372
82373    /**
82374     * Indicates whether internal text char widths can be cached
82375     * @type Boolean
82376     * @default
82377     */
82378    caching: true,
82379
82380    /**
82381     * DOM container to append the hiddenTextarea.
82382     * An alternative to attaching to the document.body.
82383     * Useful to reduce laggish redraw of the full document.body tree and
82384     * also with modals event capturing that won't let the textarea take focus.
82385     * @type HTMLElement
82386     * @default
82387     */
82388    hiddenTextareaContainer: null,
82389
82390    /**
82391     * @private
82392     */
82393    _reSpace: /\s|\n/,
82394
82395    /**
82396     * @private
82397     */
82398    _currentCursorOpacity: 0,
82399
82400    /**
82401     * @private
82402     */
82403    _selectionDirection: null,
82404
82405    /**
82406     * @private
82407     */
82408    _abortCursorAnimation: false,
82409
82410    /**
82411     * @private
82412     */
82413    __widthOfSpace: [],
82414
82415    /**
82416     * Helps determining when the text is in composition, so that the cursor
82417     * rendering is altered.
82418     */
82419    inCompositionMode: false,
82420
82421    /**
82422     * Constructor
82423     * @param {String} text Text string
82424     * @param {Object} [options] Options object
82425     * @return {fabric.IText} thisArg
82426     */
82427    initialize: function(text, options) {
82428      this.callSuper('initialize', text, options);
82429      this.initBehavior();
82430    },
82431
82432    /**
82433     * Sets selection start (left boundary of a selection)
82434     * @param {Number} index Index to set selection start to
82435     */
82436    setSelectionStart: function(index) {
82437      index = Math.max(index, 0);
82438      this._updateAndFire('selectionStart', index);
82439    },
82440
82441    /**
82442     * Sets selection end (right boundary of a selection)
82443     * @param {Number} index Index to set selection end to
82444     */
82445    setSelectionEnd: function(index) {
82446      index = Math.min(index, this.text.length);
82447      this._updateAndFire('selectionEnd', index);
82448    },
82449
82450    /**
82451     * @private
82452     * @param {String} property 'selectionStart' or 'selectionEnd'
82453     * @param {Number} index new position of property
82454     */
82455    _updateAndFire: function(property, index) {
82456      if (this[property] !== index) {
82457        this._fireSelectionChanged();
82458        this[property] = index;
82459      }
82460      this._updateTextarea();
82461    },
82462
82463    /**
82464     * Fires the even of selection changed
82465     * @private
82466     */
82467    _fireSelectionChanged: function() {
82468      this.fire('selection:changed');
82469      this.canvas && this.canvas.fire('text:selection:changed', { target: this });
82470    },
82471
82472    /**
82473     * Initialize text dimensions. Render all text on given context
82474     * or on a offscreen canvas to get the text width with measureText.
82475     * Updates this.width and this.height with the proper values.
82476     * Does not return dimensions.
82477     * @private
82478     */
82479    initDimensions: function() {
82480      this.isEditing && this.initDelayedCursor();
82481      this.clearContextTop();
82482      this.callSuper('initDimensions');
82483    },
82484
82485    /**
82486     * @private
82487     * @param {CanvasRenderingContext2D} ctx Context to render on
82488     */
82489    render: function(ctx) {
82490      this.clearContextTop();
82491      this.callSuper('render', ctx);
82492      // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor
82493      // the correct position but not at every cursor animation.
82494      this.cursorOffsetCache = { };
82495      this.renderCursorOrSelection();
82496    },
82497
82498    /**
82499     * @private
82500     * @param {CanvasRenderingContext2D} ctx Context to render on
82501     */
82502    _render: function(ctx) {
82503      this.callSuper('_render', ctx);
82504    },
82505
82506    /**
82507     * Prepare and clean the contextTop
82508     */
82509    clearContextTop: function(skipRestore) {
82510      if (!this.isEditing || !this.canvas || !this.canvas.contextTop) {
82511        return;
82512      }
82513      var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform;
82514      ctx.save();
82515      ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
82516      this.transform(ctx);
82517      this._clearTextArea(ctx);
82518      skipRestore || ctx.restore();
82519    },
82520    /**
82521     * Renders cursor or selection (depending on what exists)
82522     * it does on the contextTop. If contextTop is not available, do nothing.
82523     */
82524    renderCursorOrSelection: function() {
82525      if (!this.isEditing || !this.canvas || !this.canvas.contextTop) {
82526        return;
82527      }
82528      var boundaries = this._getCursorBoundaries(),
82529          ctx = this.canvas.contextTop;
82530      this.clearContextTop(true);
82531      if (this.selectionStart === this.selectionEnd) {
82532        this.renderCursor(boundaries, ctx);
82533      }
82534      else {
82535        this.renderSelection(boundaries, ctx);
82536      }
82537      ctx.restore();
82538    },
82539
82540    _clearTextArea: function(ctx) {
82541      // we add 4 pixel, to be sure to do not leave any pixel out
82542      var width = this.width + 4, height = this.height + 4;
82543      ctx.clearRect(-width / 2, -height / 2, width, height);
82544    },
82545
82546    /**
82547     * Returns cursor boundaries (left, top, leftOffset, topOffset)
82548     * @private
82549     * @param {Array} chars Array of characters
82550     * @param {String} typeOfBoundaries
82551     */
82552    _getCursorBoundaries: function(position) {
82553
82554      // left/top are left/top of entire text box
82555      // leftOffset/topOffset are offset from that left/top point of a text box
82556
82557      if (typeof position === 'undefined') {
82558        position = this.selectionStart;
82559      }
82560
82561      var left = this._getLeftOffset(),
82562          top = this._getTopOffset(),
82563          offsets = this._getCursorBoundariesOffsets(position);
82564      return {
82565        left: left,
82566        top: top,
82567        leftOffset: offsets.left,
82568        topOffset: offsets.top
82569      };
82570    },
82571
82572    /**
82573     * @private
82574     */
82575    _getCursorBoundariesOffsets: function(position) {
82576      if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {
82577        return this.cursorOffsetCache;
82578      }
82579      var lineLeftOffset,
82580          lineIndex,
82581          charIndex,
82582          topOffset = 0,
82583          leftOffset = 0,
82584          boundaries,
82585          cursorPosition = this.get2DCursorLocation(position);
82586      charIndex = cursorPosition.charIndex;
82587      lineIndex = cursorPosition.lineIndex;
82588      for (var i = 0; i < lineIndex; i++) {
82589        topOffset += this.getHeightOfLine(i);
82590      }
82591      lineLeftOffset = this._getLineLeftOffset(lineIndex);
82592      var bound = this.__charBounds[lineIndex][charIndex];
82593      bound && (leftOffset = bound.left);
82594      if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) {
82595        leftOffset -= this._getWidthOfCharSpacing();
82596      }
82597      boundaries = {
82598        top: topOffset,
82599        left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0),
82600      };
82601      if (this.direction === 'rtl') {
82602        boundaries.left *= -1;
82603      }
82604      this.cursorOffsetCache = boundaries;
82605      return this.cursorOffsetCache;
82606    },
82607
82608    /**
82609     * Renders cursor
82610     * @param {Object} boundaries
82611     * @param {CanvasRenderingContext2D} ctx transformed context to draw on
82612     */
82613    renderCursor: function(boundaries, ctx) {
82614      var cursorLocation = this.get2DCursorLocation(),
82615          lineIndex = cursorLocation.lineIndex,
82616          charIndex = cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,
82617          charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'),
82618          multiplier = this.scaleX * this.canvas.getZoom(),
82619          cursorWidth = this.cursorWidth / multiplier,
82620          topOffset = boundaries.topOffset,
82621          dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY');
82622      topOffset += (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight
82623        - charHeight * (1 - this._fontSizeFraction);
82624
82625      if (this.inCompositionMode) {
82626        this.renderSelection(boundaries, ctx);
82627      }
82628      ctx.fillStyle = this.cursorColor || this.getValueOfPropertyAt(lineIndex, charIndex, 'fill');
82629      ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity;
82630      ctx.fillRect(
82631        boundaries.left + boundaries.leftOffset - cursorWidth / 2,
82632        topOffset + boundaries.top + dy,
82633        cursorWidth,
82634        charHeight);
82635    },
82636
82637    /**
82638     * Renders text selection
82639     * @param {Object} boundaries Object with left/top/leftOffset/topOffset
82640     * @param {CanvasRenderingContext2D} ctx transformed context to draw on
82641     */
82642    renderSelection: function(boundaries, ctx) {
82643
82644      var selectionStart = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart,
82645          selectionEnd = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd,
82646          isJustify = this.textAlign.indexOf('justify') !== -1,
82647          start = this.get2DCursorLocation(selectionStart),
82648          end = this.get2DCursorLocation(selectionEnd),
82649          startLine = start.lineIndex,
82650          endLine = end.lineIndex,
82651          startChar = start.charIndex < 0 ? 0 : start.charIndex,
82652          endChar = end.charIndex < 0 ? 0 : end.charIndex;
82653
82654      for (var i = startLine; i <= endLine; i++) {
82655        var lineOffset = this._getLineLeftOffset(i) || 0,
82656            lineHeight = this.getHeightOfLine(i),
82657            realLineHeight = 0, boxStart = 0, boxEnd = 0;
82658
82659        if (i === startLine) {
82660          boxStart = this.__charBounds[startLine][startChar].left;
82661        }
82662        if (i >= startLine && i < endLine) {
82663          boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5?
82664        }
82665        else if (i === endLine) {
82666          if (endChar === 0) {
82667            boxEnd = this.__charBounds[endLine][endChar].left;
82668          }
82669          else {
82670            var charSpacing = this._getWidthOfCharSpacing();
82671            boxEnd = this.__charBounds[endLine][endChar - 1].left
82672              + this.__charBounds[endLine][endChar - 1].width - charSpacing;
82673          }
82674        }
82675        realLineHeight = lineHeight;
82676        if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {
82677          lineHeight /= this.lineHeight;
82678        }
82679        var drawStart = boundaries.left + lineOffset + boxStart,
82680            drawWidth = boxEnd - boxStart,
82681            drawHeight = lineHeight, extraTop = 0;
82682        if (this.inCompositionMode) {
82683          ctx.fillStyle = this.compositionColor || 'black';
82684          drawHeight = 1;
82685          extraTop = lineHeight;
82686        }
82687        else {
82688          ctx.fillStyle = this.selectionColor;
82689        }
82690        if (this.direction === 'rtl') {
82691          drawStart = this.width - drawStart - drawWidth;
82692        }
82693        ctx.fillRect(
82694          drawStart,
82695          boundaries.top + boundaries.topOffset + extraTop,
82696          drawWidth,
82697          drawHeight);
82698        boundaries.topOffset += realLineHeight;
82699      }
82700    },
82701
82702    /**
82703     * High level function to know the height of the cursor.
82704     * the currentChar is the one that precedes the cursor
82705     * Returns fontSize of char at the current cursor
82706     * Unused from the library, is for the end user
82707     * @return {Number} Character font size
82708     */
82709    getCurrentCharFontSize: function() {
82710      var cp = this._getCurrentCharIndex();
82711      return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');
82712    },
82713
82714    /**
82715     * High level function to know the color of the cursor.
82716     * the currentChar is the one that precedes the cursor
82717     * Returns color (fill) of char at the current cursor
82718     * if the text object has a pattern or gradient for filler, it will return that.
82719     * Unused by the library, is for the end user
82720     * @return {String | fabric.Gradient | fabric.Pattern} Character color (fill)
82721     */
82722    getCurrentCharColor: function() {
82723      var cp = this._getCurrentCharIndex();
82724      return this.getValueOfPropertyAt(cp.l, cp.c, 'fill');
82725    },
82726
82727    /**
82728     * Returns the cursor position for the getCurrent.. functions
82729     * @private
82730     */
82731    _getCurrentCharIndex: function() {
82732      var cursorPosition = this.get2DCursorLocation(this.selectionStart, true),
82733          charIndex = cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;
82734      return { l: cursorPosition.lineIndex, c: charIndex };
82735    }
82736  });
82737
82738  /**
82739   * Returns fabric.IText instance from an object representation
82740   * @static
82741   * @memberOf fabric.IText
82742   * @param {Object} object Object to create an instance from
82743   * @param {function} [callback] invoked with new instance as argument
82744   */
82745  fabric.IText.fromObject = function(object, callback) {
82746    parseDecoration(object);
82747    if (object.styles) {
82748      for (var i in object.styles) {
82749        for (var j in object.styles[i]) {
82750          parseDecoration(object.styles[i][j]);
82751        }
82752      }
82753    }
82754    fabric.Object._fromObject('IText', object, callback, 'text');
82755  };
82756})();
82757
82758
82759(function() {
82760
82761  var clone = fabric.util.object.clone;
82762
82763  fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {
82764
82765    /**
82766     * Initializes all the interactive behavior of IText
82767     */
82768    initBehavior: function() {
82769      this.initAddedHandler();
82770      this.initRemovedHandler();
82771      this.initCursorSelectionHandlers();
82772      this.initDoubleClickSimulation();
82773      this.mouseMoveHandler = this.mouseMoveHandler.bind(this);
82774    },
82775
82776    onDeselect: function() {
82777      this.isEditing && this.exitEditing();
82778      this.selected = false;
82779    },
82780
82781    /**
82782     * Initializes "added" event handler
82783     */
82784    initAddedHandler: function() {
82785      var _this = this;
82786      this.on('added', function() {
82787        var canvas = _this.canvas;
82788        if (canvas) {
82789          if (!canvas._hasITextHandlers) {
82790            canvas._hasITextHandlers = true;
82791            _this._initCanvasHandlers(canvas);
82792          }
82793          canvas._iTextInstances = canvas._iTextInstances || [];
82794          canvas._iTextInstances.push(_this);
82795        }
82796      });
82797    },
82798
82799    initRemovedHandler: function() {
82800      var _this = this;
82801      this.on('removed', function() {
82802        var canvas = _this.canvas;
82803        if (canvas) {
82804          canvas._iTextInstances = canvas._iTextInstances || [];
82805          fabric.util.removeFromArray(canvas._iTextInstances, _this);
82806          if (canvas._iTextInstances.length === 0) {
82807            canvas._hasITextHandlers = false;
82808            _this._removeCanvasHandlers(canvas);
82809          }
82810        }
82811      });
82812    },
82813
82814    /**
82815     * register canvas event to manage exiting on other instances
82816     * @private
82817     */
82818    _initCanvasHandlers: function(canvas) {
82819      canvas._mouseUpITextHandler = function() {
82820        if (canvas._iTextInstances) {
82821          canvas._iTextInstances.forEach(function(obj) {
82822            obj.__isMousedown = false;
82823          });
82824        }
82825      };
82826      canvas.on('mouse:up', canvas._mouseUpITextHandler);
82827    },
82828
82829    /**
82830     * remove canvas event to manage exiting on other instances
82831     * @private
82832     */
82833    _removeCanvasHandlers: function(canvas) {
82834      canvas.off('mouse:up', canvas._mouseUpITextHandler);
82835    },
82836
82837    /**
82838     * @private
82839     */
82840    _tick: function() {
82841      this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete');
82842    },
82843
82844    /**
82845     * @private
82846     */
82847    _animateCursor: function(obj, targetOpacity, duration, completeMethod) {
82848
82849      var tickState;
82850
82851      tickState = {
82852        isAborted: false,
82853        abort: function() {
82854          this.isAborted = true;
82855        },
82856      };
82857
82858      obj.animate('_currentCursorOpacity', targetOpacity, {
82859        duration: duration,
82860        onComplete: function() {
82861          if (!tickState.isAborted) {
82862            obj[completeMethod]();
82863          }
82864        },
82865        onChange: function() {
82866          // we do not want to animate a selection, only cursor
82867          if (obj.canvas && obj.selectionStart === obj.selectionEnd) {
82868            obj.renderCursorOrSelection();
82869          }
82870        },
82871        abort: function() {
82872          return tickState.isAborted;
82873        }
82874      });
82875      return tickState;
82876    },
82877
82878    /**
82879     * @private
82880     */
82881    _onTickComplete: function() {
82882
82883      var _this = this;
82884
82885      if (this._cursorTimeout1) {
82886        clearTimeout(this._cursorTimeout1);
82887      }
82888      this._cursorTimeout1 = setTimeout(function() {
82889        _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, '_tick');
82890      }, 100);
82891    },
82892
82893    /**
82894     * Initializes delayed cursor
82895     */
82896    initDelayedCursor: function(restart) {
82897      var _this = this,
82898          delay = restart ? 0 : this.cursorDelay;
82899
82900      this.abortCursorAnimation();
82901      this._currentCursorOpacity = 1;
82902      this._cursorTimeout2 = setTimeout(function() {
82903        _this._tick();
82904      }, delay);
82905    },
82906
82907    /**
82908     * Aborts cursor animation and clears all timeouts
82909     */
82910    abortCursorAnimation: function() {
82911      var shouldClear = this._currentTickState || this._currentTickCompleteState,
82912          canvas = this.canvas;
82913      this._currentTickState && this._currentTickState.abort();
82914      this._currentTickCompleteState && this._currentTickCompleteState.abort();
82915
82916      clearTimeout(this._cursorTimeout1);
82917      clearTimeout(this._cursorTimeout2);
82918
82919      this._currentCursorOpacity = 0;
82920      // to clear just itext area we need to transform the context
82921      // it may not be worth it
82922      if (shouldClear && canvas) {
82923        canvas.clearContext(canvas.contextTop || canvas.contextContainer);
82924      }
82925
82926    },
82927
82928    /**
82929     * Selects entire text
82930     * @return {fabric.IText} thisArg
82931     * @chainable
82932     */
82933    selectAll: function() {
82934      this.selectionStart = 0;
82935      this.selectionEnd = this._text.length;
82936      this._fireSelectionChanged();
82937      this._updateTextarea();
82938      return this;
82939    },
82940
82941    /**
82942     * Returns selected text
82943     * @return {String}
82944     */
82945    getSelectedText: function() {
82946      return this._text.slice(this.selectionStart, this.selectionEnd).join('');
82947    },
82948
82949    /**
82950     * Find new selection index representing start of current word according to current selection index
82951     * @param {Number} startFrom Current selection index
82952     * @return {Number} New selection index
82953     */
82954    findWordBoundaryLeft: function(startFrom) {
82955      var offset = 0, index = startFrom - 1;
82956
82957      // remove space before cursor first
82958      if (this._reSpace.test(this._text[index])) {
82959        while (this._reSpace.test(this._text[index])) {
82960          offset++;
82961          index--;
82962        }
82963      }
82964      while (/\S/.test(this._text[index]) && index > -1) {
82965        offset++;
82966        index--;
82967      }
82968
82969      return startFrom - offset;
82970    },
82971
82972    /**
82973     * Find new selection index representing end of current word according to current selection index
82974     * @param {Number} startFrom Current selection index
82975     * @return {Number} New selection index
82976     */
82977    findWordBoundaryRight: function(startFrom) {
82978      var offset = 0, index = startFrom;
82979
82980      // remove space after cursor first
82981      if (this._reSpace.test(this._text[index])) {
82982        while (this._reSpace.test(this._text[index])) {
82983          offset++;
82984          index++;
82985        }
82986      }
82987      while (/\S/.test(this._text[index]) && index < this._text.length) {
82988        offset++;
82989        index++;
82990      }
82991
82992      return startFrom + offset;
82993    },
82994
82995    /**
82996     * Find new selection index representing start of current line according to current selection index
82997     * @param {Number} startFrom Current selection index
82998     * @return {Number} New selection index
82999     */
83000    findLineBoundaryLeft: function(startFrom) {
83001      var offset = 0, index = startFrom - 1;
83002
83003      while (!/\n/.test(this._text[index]) && index > -1) {
83004        offset++;
83005        index--;
83006      }
83007
83008      return startFrom - offset;
83009    },
83010
83011    /**
83012     * Find new selection index representing end of current line according to current selection index
83013     * @param {Number} startFrom Current selection index
83014     * @return {Number} New selection index
83015     */
83016    findLineBoundaryRight: function(startFrom) {
83017      var offset = 0, index = startFrom;
83018
83019      while (!/\n/.test(this._text[index]) && index < this._text.length) {
83020        offset++;
83021        index++;
83022      }
83023
83024      return startFrom + offset;
83025    },
83026
83027    /**
83028     * Finds index corresponding to beginning or end of a word
83029     * @param {Number} selectionStart Index of a character
83030     * @param {Number} direction 1 or -1
83031     * @return {Number} Index of the beginning or end of a word
83032     */
83033    searchWordBoundary: function(selectionStart, direction) {
83034      var text = this._text,
83035          index     = this._reSpace.test(text[selectionStart]) ? selectionStart - 1 : selectionStart,
83036          _char     = text[index],
83037          // wrong
83038          reNonWord = fabric.reNonWord;
83039
83040      while (!reNonWord.test(_char) && index > 0 && index < text.length) {
83041        index += direction;
83042        _char = text[index];
83043      }
83044      if (reNonWord.test(_char)) {
83045        index += direction === 1 ? 0 : 1;
83046      }
83047      return index;
83048    },
83049
83050    /**
83051     * Selects a word based on the index
83052     * @param {Number} selectionStart Index of a character
83053     */
83054    selectWord: function(selectionStart) {
83055      selectionStart = selectionStart || this.selectionStart;
83056      var newSelectionStart = this.searchWordBoundary(selectionStart, -1), /* search backwards */
83057          newSelectionEnd = this.searchWordBoundary(selectionStart, 1); /* search forward */
83058
83059      this.selectionStart = newSelectionStart;
83060      this.selectionEnd = newSelectionEnd;
83061      this._fireSelectionChanged();
83062      this._updateTextarea();
83063      this.renderCursorOrSelection();
83064    },
83065
83066    /**
83067     * Selects a line based on the index
83068     * @param {Number} selectionStart Index of a character
83069     * @return {fabric.IText} thisArg
83070     * @chainable
83071     */
83072    selectLine: function(selectionStart) {
83073      selectionStart = selectionStart || this.selectionStart;
83074      var newSelectionStart = this.findLineBoundaryLeft(selectionStart),
83075          newSelectionEnd = this.findLineBoundaryRight(selectionStart);
83076
83077      this.selectionStart = newSelectionStart;
83078      this.selectionEnd = newSelectionEnd;
83079      this._fireSelectionChanged();
83080      this._updateTextarea();
83081      return this;
83082    },
83083
83084    /**
83085     * Enters editing state
83086     * @return {fabric.IText} thisArg
83087     * @chainable
83088     */
83089    enterEditing: function(e) {
83090      if (this.isEditing || !this.editable) {
83091        return;
83092      }
83093
83094      if (this.canvas) {
83095        this.canvas.calcOffset();
83096        this.exitEditingOnOthers(this.canvas);
83097      }
83098
83099      this.isEditing = true;
83100
83101      this.initHiddenTextarea(e);
83102      this.hiddenTextarea.focus();
83103      this.hiddenTextarea.value = this.text;
83104      this._updateTextarea();
83105      this._saveEditingProps();
83106      this._setEditingProps();
83107      this._textBeforeEdit = this.text;
83108
83109      this._tick();
83110      this.fire('editing:entered');
83111      this._fireSelectionChanged();
83112      if (!this.canvas) {
83113        return this;
83114      }
83115      this.canvas.fire('text:editing:entered', { target: this });
83116      this.initMouseMoveHandler();
83117      this.canvas.requestRenderAll();
83118      return this;
83119    },
83120
83121    exitEditingOnOthers: function(canvas) {
83122      if (canvas._iTextInstances) {
83123        canvas._iTextInstances.forEach(function(obj) {
83124          obj.selected = false;
83125          if (obj.isEditing) {
83126            obj.exitEditing();
83127          }
83128        });
83129      }
83130    },
83131
83132    /**
83133     * Initializes "mousemove" event handler
83134     */
83135    initMouseMoveHandler: function() {
83136      this.canvas.on('mouse:move', this.mouseMoveHandler);
83137    },
83138
83139    /**
83140     * @private
83141     */
83142    mouseMoveHandler: function(options) {
83143      if (!this.__isMousedown || !this.isEditing) {
83144        return;
83145      }
83146
83147      var newSelectionStart = this.getSelectionStartFromPointer(options.e),
83148          currentStart = this.selectionStart,
83149          currentEnd = this.selectionEnd;
83150      if (
83151        (newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd)
83152        &&
83153        (currentStart === newSelectionStart || currentEnd === newSelectionStart)
83154      ) {
83155        return;
83156      }
83157      if (newSelectionStart > this.__selectionStartOnMouseDown) {
83158        this.selectionStart = this.__selectionStartOnMouseDown;
83159        this.selectionEnd = newSelectionStart;
83160      }
83161      else {
83162        this.selectionStart = newSelectionStart;
83163        this.selectionEnd = this.__selectionStartOnMouseDown;
83164      }
83165      if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) {
83166        this.restartCursorIfNeeded();
83167        this._fireSelectionChanged();
83168        this._updateTextarea();
83169        this.renderCursorOrSelection();
83170      }
83171    },
83172
83173    /**
83174     * @private
83175     */
83176    _setEditingProps: function() {
83177      this.hoverCursor = 'text';
83178
83179      if (this.canvas) {
83180        this.canvas.defaultCursor = this.canvas.moveCursor = 'text';
83181      }
83182
83183      this.borderColor = this.editingBorderColor;
83184      this.hasControls = this.selectable = false;
83185      this.lockMovementX = this.lockMovementY = true;
83186    },
83187
83188    /**
83189     * convert from textarea to grapheme indexes
83190     */
83191    fromStringToGraphemeSelection: function(start, end, text) {
83192      var smallerTextStart = text.slice(0, start),
83193          graphemeStart = fabric.util.string.graphemeSplit(smallerTextStart).length;
83194      if (start === end) {
83195        return { selectionStart: graphemeStart, selectionEnd: graphemeStart };
83196      }
83197      var smallerTextEnd = text.slice(start, end),
83198          graphemeEnd = fabric.util.string.graphemeSplit(smallerTextEnd).length;
83199      return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd };
83200    },
83201
83202    /**
83203     * convert from fabric to textarea values
83204     */
83205    fromGraphemeToStringSelection: function(start, end, _text) {
83206      var smallerTextStart = _text.slice(0, start),
83207          graphemeStart = smallerTextStart.join('').length;
83208      if (start === end) {
83209        return { selectionStart: graphemeStart, selectionEnd: graphemeStart };
83210      }
83211      var smallerTextEnd = _text.slice(start, end),
83212          graphemeEnd = smallerTextEnd.join('').length;
83213      return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd };
83214    },
83215
83216    /**
83217     * @private
83218     */
83219    _updateTextarea: function() {
83220      this.cursorOffsetCache = { };
83221      if (!this.hiddenTextarea) {
83222        return;
83223      }
83224      if (!this.inCompositionMode) {
83225        var newSelection = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text);
83226        this.hiddenTextarea.selectionStart = newSelection.selectionStart;
83227        this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;
83228      }
83229      this.updateTextareaPosition();
83230    },
83231
83232    /**
83233     * @private
83234     */
83235    updateFromTextArea: function() {
83236      if (!this.hiddenTextarea) {
83237        return;
83238      }
83239      this.cursorOffsetCache = { };
83240      this.text = this.hiddenTextarea.value;
83241      if (this._shouldClearDimensionCache()) {
83242        this.initDimensions();
83243        this.setCoords();
83244      }
83245      var newSelection = this.fromStringToGraphemeSelection(
83246        this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value);
83247      this.selectionEnd = this.selectionStart = newSelection.selectionEnd;
83248      if (!this.inCompositionMode) {
83249        this.selectionStart = newSelection.selectionStart;
83250      }
83251      this.updateTextareaPosition();
83252    },
83253
83254    /**
83255     * @private
83256     */
83257    updateTextareaPosition: function() {
83258      if (this.selectionStart === this.selectionEnd) {
83259        var style = this._calcTextareaPosition();
83260        this.hiddenTextarea.style.left = style.left;
83261        this.hiddenTextarea.style.top = style.top;
83262      }
83263    },
83264
83265    /**
83266     * @private
83267     * @return {Object} style contains style for hiddenTextarea
83268     */
83269    _calcTextareaPosition: function() {
83270      if (!this.canvas) {
83271        return { x: 1, y: 1 };
83272      }
83273      var desiredPosition = this.inCompositionMode ? this.compositionStart : this.selectionStart,
83274          boundaries = this._getCursorBoundaries(desiredPosition),
83275          cursorLocation = this.get2DCursorLocation(desiredPosition),
83276          lineIndex = cursorLocation.lineIndex,
83277          charIndex = cursorLocation.charIndex,
83278          charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') * this.lineHeight,
83279          leftOffset = boundaries.leftOffset,
83280          m = this.calcTransformMatrix(),
83281          p = {
83282            x: boundaries.left + leftOffset,
83283            y: boundaries.top + boundaries.topOffset + charHeight
83284          },
83285          retinaScaling = this.canvas.getRetinaScaling(),
83286          upperCanvas = this.canvas.upperCanvasEl,
83287          upperCanvasWidth = upperCanvas.width / retinaScaling,
83288          upperCanvasHeight = upperCanvas.height / retinaScaling,
83289          maxWidth = upperCanvasWidth - charHeight,
83290          maxHeight = upperCanvasHeight - charHeight,
83291          scaleX = upperCanvas.clientWidth / upperCanvasWidth,
83292          scaleY = upperCanvas.clientHeight / upperCanvasHeight;
83293
83294      p = fabric.util.transformPoint(p, m);
83295      p = fabric.util.transformPoint(p, this.canvas.viewportTransform);
83296      p.x *= scaleX;
83297      p.y *= scaleY;
83298      if (p.x < 0) {
83299        p.x = 0;
83300      }
83301      if (p.x > maxWidth) {
83302        p.x = maxWidth;
83303      }
83304      if (p.y < 0) {
83305        p.y = 0;
83306      }
83307      if (p.y > maxHeight) {
83308        p.y = maxHeight;
83309      }
83310
83311      // add canvas offset on document
83312      p.x += this.canvas._offset.left;
83313      p.y += this.canvas._offset.top;
83314
83315      return { left: p.x + 'px', top: p.y + 'px', fontSize: charHeight + 'px', charHeight: charHeight };
83316    },
83317
83318    /**
83319     * @private
83320     */
83321    _saveEditingProps: function() {
83322      this._savedProps = {
83323        hasControls: this.hasControls,
83324        borderColor: this.borderColor,
83325        lockMovementX: this.lockMovementX,
83326        lockMovementY: this.lockMovementY,
83327        hoverCursor: this.hoverCursor,
83328        selectable: this.selectable,
83329        defaultCursor: this.canvas && this.canvas.defaultCursor,
83330        moveCursor: this.canvas && this.canvas.moveCursor
83331      };
83332    },
83333
83334    /**
83335     * @private
83336     */
83337    _restoreEditingProps: function() {
83338      if (!this._savedProps) {
83339        return;
83340      }
83341
83342      this.hoverCursor = this._savedProps.hoverCursor;
83343      this.hasControls = this._savedProps.hasControls;
83344      this.borderColor = this._savedProps.borderColor;
83345      this.selectable = this._savedProps.selectable;
83346      this.lockMovementX = this._savedProps.lockMovementX;
83347      this.lockMovementY = this._savedProps.lockMovementY;
83348
83349      if (this.canvas) {
83350        this.canvas.defaultCursor = this._savedProps.defaultCursor;
83351        this.canvas.moveCursor = this._savedProps.moveCursor;
83352      }
83353    },
83354
83355    /**
83356     * Exits from editing state
83357     * @return {fabric.IText} thisArg
83358     * @chainable
83359     */
83360    exitEditing: function() {
83361      var isTextChanged = (this._textBeforeEdit !== this.text);
83362      var hiddenTextarea = this.hiddenTextarea;
83363      this.selected = false;
83364      this.isEditing = false;
83365
83366      this.selectionEnd = this.selectionStart;
83367
83368      if (hiddenTextarea) {
83369        hiddenTextarea.blur && hiddenTextarea.blur();
83370        hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea);
83371      }
83372      this.hiddenTextarea = null;
83373      this.abortCursorAnimation();
83374      this._restoreEditingProps();
83375      this._currentCursorOpacity = 0;
83376      if (this._shouldClearDimensionCache()) {
83377        this.initDimensions();
83378        this.setCoords();
83379      }
83380      this.fire('editing:exited');
83381      isTextChanged && this.fire('modified');
83382      if (this.canvas) {
83383        this.canvas.off('mouse:move', this.mouseMoveHandler);
83384        this.canvas.fire('text:editing:exited', { target: this });
83385        isTextChanged && this.canvas.fire('object:modified', { target: this });
83386      }
83387      return this;
83388    },
83389
83390    /**
83391     * @private
83392     */
83393    _removeExtraneousStyles: function() {
83394      for (var prop in this.styles) {
83395        if (!this._textLines[prop]) {
83396          delete this.styles[prop];
83397        }
83398      }
83399    },
83400
83401    /**
83402     * remove and reflow a style block from start to end.
83403     * @param {Number} start linear start position for removal (included in removal)
83404     * @param {Number} end linear end position for removal ( excluded from removal )
83405     */
83406    removeStyleFromTo: function(start, end) {
83407      var cursorStart = this.get2DCursorLocation(start, true),
83408          cursorEnd = this.get2DCursorLocation(end, true),
83409          lineStart = cursorStart.lineIndex,
83410          charStart = cursorStart.charIndex,
83411          lineEnd = cursorEnd.lineIndex,
83412          charEnd = cursorEnd.charIndex,
83413          i, styleObj;
83414      if (lineStart !== lineEnd) {
83415        // step1 remove the trailing of lineStart
83416        if (this.styles[lineStart]) {
83417          for (i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) {
83418            delete this.styles[lineStart][i];
83419          }
83420        }
83421        // step2 move the trailing of lineEnd to lineStart if needed
83422        if (this.styles[lineEnd]) {
83423          for (i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) {
83424            styleObj = this.styles[lineEnd][i];
83425            if (styleObj) {
83426              this.styles[lineStart] || (this.styles[lineStart] = { });
83427              this.styles[lineStart][charStart + i - charEnd] = styleObj;
83428            }
83429          }
83430        }
83431        // step3 detects lines will be completely removed.
83432        for (i = lineStart + 1; i <= lineEnd; i++) {
83433          delete this.styles[i];
83434        }
83435        // step4 shift remaining lines.
83436        this.shiftLineStyles(lineEnd, lineStart - lineEnd);
83437      }
83438      else {
83439        // remove and shift left on the same line
83440        if (this.styles[lineStart]) {
83441          styleObj = this.styles[lineStart];
83442          var diff = charEnd - charStart, numericChar, _char;
83443          for (i = charStart; i < charEnd; i++) {
83444            delete styleObj[i];
83445          }
83446          for (_char in this.styles[lineStart]) {
83447            numericChar = parseInt(_char, 10);
83448            if (numericChar >= charEnd) {
83449              styleObj[numericChar - diff] = styleObj[_char];
83450              delete styleObj[_char];
83451            }
83452          }
83453        }
83454      }
83455    },
83456
83457    /**
83458     * Shifts line styles up or down
83459     * @param {Number} lineIndex Index of a line
83460     * @param {Number} offset Can any number?
83461     */
83462    shiftLineStyles: function(lineIndex, offset) {
83463      // shift all line styles by offset upward or downward
83464      // do not clone deep. we need new array, not new style objects
83465      var clonedStyles = clone(this.styles);
83466      for (var line in this.styles) {
83467        var numericLine = parseInt(line, 10);
83468        if (numericLine > lineIndex) {
83469          this.styles[numericLine + offset] = clonedStyles[numericLine];
83470          if (!clonedStyles[numericLine - offset]) {
83471            delete this.styles[numericLine];
83472          }
83473        }
83474      }
83475    },
83476
83477    restartCursorIfNeeded: function() {
83478      if (!this._currentTickState || this._currentTickState.isAborted
83479        || !this._currentTickCompleteState || this._currentTickCompleteState.isAborted
83480      ) {
83481        this.initDelayedCursor();
83482      }
83483    },
83484
83485    /**
83486     * Handle insertion of more consecutive style lines for when one or more
83487     * newlines gets added to the text. Since current style needs to be shifted
83488     * first we shift the current style of the number lines needed, then we add
83489     * new lines from the last to the first.
83490     * @param {Number} lineIndex Index of a line
83491     * @param {Number} charIndex Index of a char
83492     * @param {Number} qty number of lines to add
83493     * @param {Array} copiedStyle Array of objects styles
83494     */
83495    insertNewlineStyleObject: function(lineIndex, charIndex, qty, copiedStyle) {
83496      var currentCharStyle,
83497          newLineStyles = {},
83498          somethingAdded = false,
83499          isEndOfLine = this._unwrappedTextLines[lineIndex].length === charIndex;
83500
83501      qty || (qty = 1);
83502      this.shiftLineStyles(lineIndex, qty);
83503      if (this.styles[lineIndex]) {
83504        currentCharStyle = this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1];
83505      }
83506      // we clone styles of all chars
83507      // after cursor onto the current line
83508      for (var index in this.styles[lineIndex]) {
83509        var numIndex = parseInt(index, 10);
83510        if (numIndex >= charIndex) {
83511          somethingAdded = true;
83512          newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];
83513          // remove lines from the previous line since they're on a new line now
83514          if (!(isEndOfLine && charIndex === 0)) {
83515            delete this.styles[lineIndex][index];
83516          }
83517        }
83518      }
83519      var styleCarriedOver = false;
83520      if (somethingAdded && !isEndOfLine) {
83521        // if is end of line, the extra style we copied
83522        // is probably not something we want
83523        this.styles[lineIndex + qty] = newLineStyles;
83524        styleCarriedOver = true;
83525      }
83526      if (styleCarriedOver) {
83527        // skip the last line of since we already prepared it.
83528        qty--;
83529      }
83530      // for the all the lines or all the other lines
83531      // we clone current char style onto the next (otherwise empty) line
83532      while (qty > 0) {
83533        if (copiedStyle && copiedStyle[qty - 1]) {
83534          this.styles[lineIndex + qty] = { 0: clone(copiedStyle[qty - 1]) };
83535        }
83536        else if (currentCharStyle) {
83537          this.styles[lineIndex + qty] = { 0: clone(currentCharStyle) };
83538        }
83539        else {
83540          delete this.styles[lineIndex + qty];
83541        }
83542        qty--;
83543      }
83544      this._forceClearCache = true;
83545    },
83546
83547    /**
83548     * Inserts style object for a given line/char index
83549     * @param {Number} lineIndex Index of a line
83550     * @param {Number} charIndex Index of a char
83551     * @param {Number} quantity number Style object to insert, if given
83552     * @param {Array} copiedStyle array of style objects
83553     */
83554    insertCharStyleObject: function(lineIndex, charIndex, quantity, copiedStyle) {
83555      if (!this.styles) {
83556        this.styles = {};
83557      }
83558      var currentLineStyles       = this.styles[lineIndex],
83559          currentLineStylesCloned = currentLineStyles ? clone(currentLineStyles) : {};
83560
83561      quantity || (quantity = 1);
83562      // shift all char styles by quantity forward
83563      // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4
83564      for (var index in currentLineStylesCloned) {
83565        var numericIndex = parseInt(index, 10);
83566        if (numericIndex >= charIndex) {
83567          currentLineStyles[numericIndex + quantity] = currentLineStylesCloned[numericIndex];
83568          // only delete the style if there was nothing moved there
83569          if (!currentLineStylesCloned[numericIndex - quantity]) {
83570            delete currentLineStyles[numericIndex];
83571          }
83572        }
83573      }
83574      this._forceClearCache = true;
83575      if (copiedStyle) {
83576        while (quantity--) {
83577          if (!Object.keys(copiedStyle[quantity]).length) {
83578            continue;
83579          }
83580          if (!this.styles[lineIndex]) {
83581            this.styles[lineIndex] = {};
83582          }
83583          this.styles[lineIndex][charIndex + quantity] = clone(copiedStyle[quantity]);
83584        }
83585        return;
83586      }
83587      if (!currentLineStyles) {
83588        return;
83589      }
83590      var newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];
83591      while (newStyle && quantity--) {
83592        this.styles[lineIndex][charIndex + quantity] = clone(newStyle);
83593      }
83594    },
83595
83596    /**
83597     * Inserts style object(s)
83598     * @param {Array} insertedText Characters at the location where style is inserted
83599     * @param {Number} start cursor index for inserting style
83600     * @param {Array} [copiedStyle] array of style objects to insert.
83601     */
83602    insertNewStyleBlock: function(insertedText, start, copiedStyle) {
83603      var cursorLoc = this.get2DCursorLocation(start, true),
83604          addedLines = [0], linesLength = 0;
83605      // get an array of how many char per lines are being added.
83606      for (var i = 0; i < insertedText.length; i++) {
83607        if (insertedText[i] === '\n') {
83608          linesLength++;
83609          addedLines[linesLength] = 0;
83610        }
83611        else {
83612          addedLines[linesLength]++;
83613        }
83614      }
83615      // for the first line copy the style from the current char position.
83616      if (addedLines[0] > 0) {
83617        this.insertCharStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex, addedLines[0], copiedStyle);
83618        copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);
83619      }
83620      linesLength && this.insertNewlineStyleObject(
83621        cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLength);
83622      for (var i = 1; i < linesLength; i++) {
83623        if (addedLines[i] > 0) {
83624          this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);
83625        }
83626        else if (copiedStyle) {
83627          this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];
83628        }
83629        copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);
83630      }
83631      // we use i outside the loop to get it like linesLength
83632      if (addedLines[i] > 0) {
83633        this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);
83634      }
83635    },
83636
83637    /**
83638     * Set the selectionStart and selectionEnd according to the new position of cursor
83639     * mimic the key - mouse navigation when shift is pressed.
83640     */
83641    setSelectionStartEndWithShift: function(start, end, newSelection) {
83642      if (newSelection <= start) {
83643        if (end === start) {
83644          this._selectionDirection = 'left';
83645        }
83646        else if (this._selectionDirection === 'right') {
83647          this._selectionDirection = 'left';
83648          this.selectionEnd = start;
83649        }
83650        this.selectionStart = newSelection;
83651      }
83652      else if (newSelection > start && newSelection < end) {
83653        if (this._selectionDirection === 'right') {
83654          this.selectionEnd = newSelection;
83655        }
83656        else {
83657          this.selectionStart = newSelection;
83658        }
83659      }
83660      else {
83661        // newSelection is > selection start and end
83662        if (end === start) {
83663          this._selectionDirection = 'right';
83664        }
83665        else if (this._selectionDirection === 'left') {
83666          this._selectionDirection = 'right';
83667          this.selectionStart = end;
83668        }
83669        this.selectionEnd = newSelection;
83670      }
83671    },
83672
83673    setSelectionInBoundaries: function() {
83674      var length = this.text.length;
83675      if (this.selectionStart > length) {
83676        this.selectionStart = length;
83677      }
83678      else if (this.selectionStart < 0) {
83679        this.selectionStart = 0;
83680      }
83681      if (this.selectionEnd > length) {
83682        this.selectionEnd = length;
83683      }
83684      else if (this.selectionEnd < 0) {
83685        this.selectionEnd = 0;
83686      }
83687    }
83688  });
83689})();
83690
83691
83692fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {
83693  /**
83694   * Initializes "dbclick" event handler
83695   */
83696  initDoubleClickSimulation: function() {
83697
83698    // for double click
83699    this.__lastClickTime = +new Date();
83700
83701    // for triple click
83702    this.__lastLastClickTime = +new Date();
83703
83704    this.__lastPointer = { };
83705
83706    this.on('mousedown', this.onMouseDown);
83707  },
83708
83709  /**
83710   * Default event handler to simulate triple click
83711   * @private
83712   */
83713  onMouseDown: function(options) {
83714    if (!this.canvas) {
83715      return;
83716    }
83717    this.__newClickTime = +new Date();
83718    var newPointer = options.pointer;
83719    if (this.isTripleClick(newPointer)) {
83720      this.fire('tripleclick', options);
83721      this._stopEvent(options.e);
83722    }
83723    this.__lastLastClickTime = this.__lastClickTime;
83724    this.__lastClickTime = this.__newClickTime;
83725    this.__lastPointer = newPointer;
83726    this.__lastIsEditing = this.isEditing;
83727    this.__lastSelected = this.selected;
83728  },
83729
83730  isTripleClick: function(newPointer) {
83731    return this.__newClickTime - this.__lastClickTime < 500 &&
83732        this.__lastClickTime - this.__lastLastClickTime < 500 &&
83733        this.__lastPointer.x === newPointer.x &&
83734        this.__lastPointer.y === newPointer.y;
83735  },
83736
83737  /**
83738   * @private
83739   */
83740  _stopEvent: function(e) {
83741    e.preventDefault && e.preventDefault();
83742    e.stopPropagation && e.stopPropagation();
83743  },
83744
83745  /**
83746   * Initializes event handlers related to cursor or selection
83747   */
83748  initCursorSelectionHandlers: function() {
83749    this.initMousedownHandler();
83750    this.initMouseupHandler();
83751    this.initClicks();
83752  },
83753
83754  /**
83755   * Default handler for double click, select a word
83756   */
83757  doubleClickHandler: function(options) {
83758    if (!this.isEditing) {
83759      return;
83760    }
83761    this.selectWord(this.getSelectionStartFromPointer(options.e));
83762  },
83763
83764  /**
83765   * Default handler for triple click, select a line
83766   */
83767  tripleClickHandler: function(options) {
83768    if (!this.isEditing) {
83769      return;
83770    }
83771    this.selectLine(this.getSelectionStartFromPointer(options.e));
83772  },
83773
83774  /**
83775   * Initializes double and triple click event handlers
83776   */
83777  initClicks: function() {
83778    this.on('mousedblclick', this.doubleClickHandler);
83779    this.on('tripleclick', this.tripleClickHandler);
83780  },
83781
83782  /**
83783   * Default event handler for the basic functionalities needed on _mouseDown
83784   * can be overridden to do something different.
83785   * Scope of this implementation is: find the click position, set selectionStart
83786   * find selectionEnd, initialize the drawing of either cursor or selection area
83787   * initializing a mousedDown on a text area will cancel fabricjs knowledge of
83788   * current compositionMode. It will be set to false.
83789   */
83790  _mouseDownHandler: function(options) {
83791    if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) {
83792      return;
83793    }
83794
83795    this.__isMousedown = true;
83796
83797    if (this.selected) {
83798      this.inCompositionMode = false;
83799      this.setCursorByClick(options.e);
83800    }
83801
83802    if (this.isEditing) {
83803      this.__selectionStartOnMouseDown = this.selectionStart;
83804      if (this.selectionStart === this.selectionEnd) {
83805        this.abortCursorAnimation();
83806      }
83807      this.renderCursorOrSelection();
83808    }
83809  },
83810
83811  /**
83812   * Default event handler for the basic functionalities needed on mousedown:before
83813   * can be overridden to do something different.
83814   * Scope of this implementation is: verify the object is already selected when mousing down
83815   */
83816  _mouseDownHandlerBefore: function(options) {
83817    if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) {
83818      return;
83819    }
83820    // we want to avoid that an object that was selected and then becomes unselectable,
83821    // may trigger editing mode in some way.
83822    this.selected = this === this.canvas._activeObject;
83823  },
83824
83825  /**
83826   * Initializes "mousedown" event handler
83827   */
83828  initMousedownHandler: function() {
83829    this.on('mousedown', this._mouseDownHandler);
83830    this.on('mousedown:before', this._mouseDownHandlerBefore);
83831  },
83832
83833  /**
83834   * Initializes "mouseup" event handler
83835   */
83836  initMouseupHandler: function() {
83837    this.on('mouseup', this.mouseUpHandler);
83838  },
83839
83840  /**
83841   * standard handler for mouse up, overridable
83842   * @private
83843   */
83844  mouseUpHandler: function(options) {
83845    this.__isMousedown = false;
83846    if (!this.editable || this.group ||
83847      (options.transform && options.transform.actionPerformed) ||
83848      (options.e.button && options.e.button !== 1)) {
83849      return;
83850    }
83851
83852    if (this.canvas) {
83853      var currentActive = this.canvas._activeObject;
83854      if (currentActive && currentActive !== this) {
83855        // avoid running this logic when there is an active object
83856        // this because is possible with shift click and fast clicks,
83857        // to rapidly deselect and reselect this object and trigger an enterEdit
83858        return;
83859      }
83860    }
83861
83862    if (this.__lastSelected && !this.__corner) {
83863      this.selected = false;
83864      this.__lastSelected = false;
83865      this.enterEditing(options.e);
83866      if (this.selectionStart === this.selectionEnd) {
83867        this.initDelayedCursor(true);
83868      }
83869      else {
83870        this.renderCursorOrSelection();
83871      }
83872    }
83873    else {
83874      this.selected = true;
83875    }
83876  },
83877
83878  /**
83879   * Changes cursor location in a text depending on passed pointer (x/y) object
83880   * @param {Event} e Event object
83881   */
83882  setCursorByClick: function(e) {
83883    var newSelection = this.getSelectionStartFromPointer(e),
83884        start = this.selectionStart, end = this.selectionEnd;
83885    if (e.shiftKey) {
83886      this.setSelectionStartEndWithShift(start, end, newSelection);
83887    }
83888    else {
83889      this.selectionStart = newSelection;
83890      this.selectionEnd = newSelection;
83891    }
83892    if (this.isEditing) {
83893      this._fireSelectionChanged();
83894      this._updateTextarea();
83895    }
83896  },
83897
83898  /**
83899   * Returns index of a character corresponding to where an object was clicked
83900   * @param {Event} e Event object
83901   * @return {Number} Index of a character
83902   */
83903  getSelectionStartFromPointer: function(e) {
83904    var mouseOffset = this.getLocalPointer(e),
83905        prevWidth = 0,
83906        width = 0,
83907        height = 0,
83908        charIndex = 0,
83909        lineIndex = 0,
83910        lineLeftOffset,
83911        line;
83912    for (var i = 0, len = this._textLines.length; i < len; i++) {
83913      if (height <= mouseOffset.y) {
83914        height += this.getHeightOfLine(i) * this.scaleY;
83915        lineIndex = i;
83916        if (i > 0) {
83917          charIndex += this._textLines[i - 1].length + this.missingNewlineOffset(i - 1);
83918        }
83919      }
83920      else {
83921        break;
83922      }
83923    }
83924    lineLeftOffset = this._getLineLeftOffset(lineIndex);
83925    width = lineLeftOffset * this.scaleX;
83926    line = this._textLines[lineIndex];
83927    // handling of RTL: in order to get things work correctly,
83928    // we assume RTL writing is mirrored compared to LTR writing.
83929    // so in position detection we mirror the X offset, and when is time
83930    // of rendering it, we mirror it again.
83931    if (this.direction === 'rtl') {
83932      mouseOffset.x = this.width * this.scaleX - mouseOffset.x + width;
83933    }
83934    for (var j = 0, jlen = line.length; j < jlen; j++) {
83935      prevWidth = width;
83936      // i removed something about flipX here, check.
83937      width += this.__charBounds[lineIndex][j].kernedWidth * this.scaleX;
83938      if (width <= mouseOffset.x) {
83939        charIndex++;
83940      }
83941      else {
83942        break;
83943      }
83944    }
83945    return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex, jlen);
83946  },
83947
83948  /**
83949   * @private
83950   */
83951  _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) {
83952    // we need Math.abs because when width is after the last char, the offset is given as 1, while is 0
83953    var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth,
83954        distanceBtwNextCharAndCursor = width - mouseOffset.x,
83955        offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor ||
83956          distanceBtwNextCharAndCursor < 0 ? 0 : 1,
83957        newSelectionStart = index + offset;
83958    // if object is horizontally flipped, mirror cursor location from the end
83959    if (this.flipX) {
83960      newSelectionStart = jlen - newSelectionStart;
83961    }
83962
83963    if (newSelectionStart > this._text.length) {
83964      newSelectionStart = this._text.length;
83965    }
83966
83967    return newSelectionStart;
83968  }
83969});
83970
83971
83972fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {
83973
83974  /**
83975   * Initializes hidden textarea (needed to bring up keyboard in iOS)
83976   */
83977  initHiddenTextarea: function() {
83978    this.hiddenTextarea = fabric.document.createElement('textarea');
83979    this.hiddenTextarea.setAttribute('autocapitalize', 'off');
83980    this.hiddenTextarea.setAttribute('autocorrect', 'off');
83981    this.hiddenTextarea.setAttribute('autocomplete', 'off');
83982    this.hiddenTextarea.setAttribute('spellcheck', 'false');
83983    this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', '');
83984    this.hiddenTextarea.setAttribute('wrap', 'off');
83985    var style = this._calcTextareaPosition();
83986    // line-height: 1px; was removed from the style to fix this:
83987    // https://bugs.chromium.org/p/chromium/issues/detail?id=870966
83988    this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top +
83989    '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' +
83990    ' paddingï½°top: ' + style.fontSize + ';';
83991
83992    if (this.hiddenTextareaContainer) {
83993      this.hiddenTextareaContainer.appendChild(this.hiddenTextarea);
83994    }
83995    else {
83996      fabric.document.body.appendChild(this.hiddenTextarea);
83997    }
83998
83999    fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));
84000    fabric.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this));
84001    fabric.util.addListener(this.hiddenTextarea, 'input', this.onInput.bind(this));
84002    fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this));
84003    fabric.util.addListener(this.hiddenTextarea, 'cut', this.copy.bind(this));
84004    fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this));
84005    fabric.util.addListener(this.hiddenTextarea, 'compositionstart', this.onCompositionStart.bind(this));
84006    fabric.util.addListener(this.hiddenTextarea, 'compositionupdate', this.onCompositionUpdate.bind(this));
84007    fabric.util.addListener(this.hiddenTextarea, 'compositionend', this.onCompositionEnd.bind(this));
84008
84009    if (!this._clickHandlerInitialized && this.canvas) {
84010      fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this));
84011      this._clickHandlerInitialized = true;
84012    }
84013  },
84014
84015  /**
84016   * For functionalities on keyDown
84017   * Map a special key to a function of the instance/prototype
84018   * If you need different behaviour for ESC or TAB or arrows, you have to change
84019   * this map setting the name of a function that you build on the fabric.Itext or
84020   * your prototype.
84021   * the map change will affect all Instances unless you need for only some text Instances
84022   * in that case you have to clone this object and assign your Instance.
84023   * this.keysMap = fabric.util.object.clone(this.keysMap);
84024   * The function must be in fabric.Itext.prototype.myFunction And will receive event as args[0]
84025   */
84026  keysMap: {
84027    9:  'exitEditing',
84028    27: 'exitEditing',
84029    33: 'moveCursorUp',
84030    34: 'moveCursorDown',
84031    35: 'moveCursorRight',
84032    36: 'moveCursorLeft',
84033    37: 'moveCursorLeft',
84034    38: 'moveCursorUp',
84035    39: 'moveCursorRight',
84036    40: 'moveCursorDown',
84037  },
84038
84039  keysMapRtl: {
84040    9:  'exitEditing',
84041    27: 'exitEditing',
84042    33: 'moveCursorUp',
84043    34: 'moveCursorDown',
84044    35: 'moveCursorLeft',
84045    36: 'moveCursorRight',
84046    37: 'moveCursorRight',
84047    38: 'moveCursorUp',
84048    39: 'moveCursorLeft',
84049    40: 'moveCursorDown',
84050  },
84051
84052  /**
84053   * For functionalities on keyUp + ctrl || cmd
84054   */
84055  ctrlKeysMapUp: {
84056    67: 'copy',
84057    88: 'cut'
84058  },
84059
84060  /**
84061   * For functionalities on keyDown + ctrl || cmd
84062   */
84063  ctrlKeysMapDown: {
84064    65: 'selectAll'
84065  },
84066
84067  onClick: function() {
84068    // No need to trigger click event here, focus is enough to have the keyboard appear on Android
84069    this.hiddenTextarea && this.hiddenTextarea.focus();
84070  },
84071
84072  /**
84073   * Handles keydown event
84074   * only used for arrows and combination of modifier keys.
84075   * @param {Event} e Event object
84076   */
84077  onKeyDown: function(e) {
84078    if (!this.isEditing) {
84079      return;
84080    }
84081    var keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap;
84082    if (e.keyCode in keyMap) {
84083      this[keyMap[e.keyCode]](e);
84084    }
84085    else if ((e.keyCode in this.ctrlKeysMapDown) && (e.ctrlKey || e.metaKey)) {
84086      this[this.ctrlKeysMapDown[e.keyCode]](e);
84087    }
84088    else {
84089      return;
84090    }
84091    e.stopImmediatePropagation();
84092    e.preventDefault();
84093    if (e.keyCode >= 33 && e.keyCode <= 40) {
84094      // if i press an arrow key just update selection
84095      this.inCompositionMode = false;
84096      this.clearContextTop();
84097      this.renderCursorOrSelection();
84098    }
84099    else {
84100      this.canvas && this.canvas.requestRenderAll();
84101    }
84102  },
84103
84104  /**
84105   * Handles keyup event
84106   * We handle KeyUp because ie11 and edge have difficulties copy/pasting
84107   * if a copy/cut event fired, keyup is dismissed
84108   * @param {Event} e Event object
84109   */
84110  onKeyUp: function(e) {
84111    if (!this.isEditing || this._copyDone || this.inCompositionMode) {
84112      this._copyDone = false;
84113      return;
84114    }
84115    if ((e.keyCode in this.ctrlKeysMapUp) && (e.ctrlKey || e.metaKey)) {
84116      this[this.ctrlKeysMapUp[e.keyCode]](e);
84117    }
84118    else {
84119      return;
84120    }
84121    e.stopImmediatePropagation();
84122    e.preventDefault();
84123    this.canvas && this.canvas.requestRenderAll();
84124  },
84125
84126  /**
84127   * Handles onInput event
84128   * @param {Event} e Event object
84129   */
84130  onInput: function(e) {
84131    var fromPaste = this.fromPaste;
84132    this.fromPaste = false;
84133    e && e.stopPropagation();
84134    if (!this.isEditing) {
84135      return;
84136    }
84137    // decisions about style changes.
84138    var nextText = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,
84139        charCount = this._text.length,
84140        nextCharCount = nextText.length,
84141        removedText, insertedText,
84142        charDiff = nextCharCount - charCount,
84143        selectionStart = this.selectionStart, selectionEnd = this.selectionEnd,
84144        selection = selectionStart !== selectionEnd,
84145        copiedStyle, removeFrom, removeTo;
84146    if (this.hiddenTextarea.value === '') {
84147      this.styles = { };
84148      this.updateFromTextArea();
84149      this.fire('changed');
84150      if (this.canvas) {
84151        this.canvas.fire('text:changed', { target: this });
84152        this.canvas.requestRenderAll();
84153      }
84154      return;
84155    }
84156
84157    var textareaSelection = this.fromStringToGraphemeSelection(
84158      this.hiddenTextarea.selectionStart,
84159      this.hiddenTextarea.selectionEnd,
84160      this.hiddenTextarea.value
84161    );
84162    var backDelete = selectionStart > textareaSelection.selectionStart;
84163
84164    if (selection) {
84165      removedText = this._text.slice(selectionStart, selectionEnd);
84166      charDiff += selectionEnd - selectionStart;
84167    }
84168    else if (nextCharCount < charCount) {
84169      if (backDelete) {
84170        removedText = this._text.slice(selectionEnd + charDiff, selectionEnd);
84171      }
84172      else {
84173        removedText = this._text.slice(selectionStart, selectionStart - charDiff);
84174      }
84175    }
84176    insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd);
84177    if (removedText && removedText.length) {
84178      if (insertedText.length) {
84179        // let's copy some style before deleting.
84180        // we want to copy the style before the cursor OR the style at the cursor if selection
84181        // is bigger than 0.
84182        copiedStyle = this.getSelectionStyles(selectionStart, selectionStart + 1, false);
84183        // now duplicate the style one for each inserted text.
84184        copiedStyle = insertedText.map(function() {
84185          // this return an array of references, but that is fine since we are
84186          // copying the style later.
84187          return copiedStyle[0];
84188        });
84189      }
84190      if (selection) {
84191        removeFrom = selectionStart;
84192        removeTo = selectionEnd;
84193      }
84194      else if (backDelete) {
84195        // detect differences between forwardDelete and backDelete
84196        removeFrom = selectionEnd - removedText.length;
84197        removeTo = selectionEnd;
84198      }
84199      else {
84200        removeFrom = selectionEnd;
84201        removeTo = selectionEnd + removedText.length;
84202      }
84203      this.removeStyleFromTo(removeFrom, removeTo);
84204    }
84205    if (insertedText.length) {
84206      if (fromPaste && insertedText.join('') === fabric.copiedText && !fabric.disableStyleCopyPaste) {
84207        copiedStyle = fabric.copiedTextStyle;
84208      }
84209      this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle);
84210    }
84211    this.updateFromTextArea();
84212    this.fire('changed');
84213    if (this.canvas) {
84214      this.canvas.fire('text:changed', { target: this });
84215      this.canvas.requestRenderAll();
84216    }
84217  },
84218  /**
84219   * Composition start
84220   */
84221  onCompositionStart: function() {
84222    this.inCompositionMode = true;
84223  },
84224
84225  /**
84226   * Composition end
84227   */
84228  onCompositionEnd: function() {
84229    this.inCompositionMode = false;
84230  },
84231
84232  // /**
84233  //  * Composition update
84234  //  */
84235  onCompositionUpdate: function(e) {
84236    this.compositionStart = e.target.selectionStart;
84237    this.compositionEnd = e.target.selectionEnd;
84238    this.updateTextareaPosition();
84239  },
84240
84241  /**
84242   * Copies selected text
84243   * @param {Event} e Event object
84244   */
84245  copy: function() {
84246    if (this.selectionStart === this.selectionEnd) {
84247      //do not cut-copy if no selection
84248      return;
84249    }
84250
84251    fabric.copiedText = this.getSelectedText();
84252    if (!fabric.disableStyleCopyPaste) {
84253      fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, true);
84254    }
84255    else {
84256      fabric.copiedTextStyle = null;
84257    }
84258    this._copyDone = true;
84259  },
84260
84261  /**
84262   * Pastes text
84263   * @param {Event} e Event object
84264   */
84265  paste: function() {
84266    this.fromPaste = true;
84267  },
84268
84269  /**
84270   * @private
84271   * @param {Event} e Event object
84272   * @return {Object} Clipboard data object
84273   */
84274  _getClipboardData: function(e) {
84275    return (e && e.clipboardData) || fabric.window.clipboardData;
84276  },
84277
84278  /**
84279   * Finds the width in pixels before the cursor on the same line
84280   * @private
84281   * @param {Number} lineIndex
84282   * @param {Number} charIndex
84283   * @return {Number} widthBeforeCursor width before cursor
84284   */
84285  _getWidthBeforeCursor: function(lineIndex, charIndex) {
84286    var widthBeforeCursor = this._getLineLeftOffset(lineIndex), bound;
84287
84288    if (charIndex > 0) {
84289      bound = this.__charBounds[lineIndex][charIndex - 1];
84290      widthBeforeCursor += bound.left + bound.width;
84291    }
84292    return widthBeforeCursor;
84293  },
84294
84295  /**
84296   * Gets start offset of a selection
84297   * @param {Event} e Event object
84298   * @param {Boolean} isRight
84299   * @return {Number}
84300   */
84301  getDownCursorOffset: function(e, isRight) {
84302    var selectionProp = this._getSelectionForOffset(e, isRight),
84303        cursorLocation = this.get2DCursorLocation(selectionProp),
84304        lineIndex = cursorLocation.lineIndex;
84305    // if on last line, down cursor goes to end of line
84306    if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) {
84307      // move to the end of a text
84308      return this._text.length - selectionProp;
84309    }
84310    var charIndex = cursorLocation.charIndex,
84311        widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),
84312        indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),
84313        textAfterCursor = this._textLines[lineIndex].slice(charIndex);
84314    return textAfterCursor.length + indexOnOtherLine + 1 + this.missingNewlineOffset(lineIndex);
84315  },
84316
84317  /**
84318   * private
84319   * Helps finding if the offset should be counted from Start or End
84320   * @param {Event} e Event object
84321   * @param {Boolean} isRight
84322   * @return {Number}
84323   */
84324  _getSelectionForOffset: function(e, isRight) {
84325    if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {
84326      return this.selectionEnd;
84327    }
84328    else {
84329      return this.selectionStart;
84330    }
84331  },
84332
84333  /**
84334   * @param {Event} e Event object
84335   * @param {Boolean} isRight
84336   * @return {Number}
84337   */
84338  getUpCursorOffset: function(e, isRight) {
84339    var selectionProp = this._getSelectionForOffset(e, isRight),
84340        cursorLocation = this.get2DCursorLocation(selectionProp),
84341        lineIndex = cursorLocation.lineIndex;
84342    if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {
84343      // if on first line, up cursor goes to start of line
84344      return -selectionProp;
84345    }
84346    var charIndex = cursorLocation.charIndex,
84347        widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),
84348        indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),
84349        textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),
84350        missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1);
84351    // return a negative offset
84352    return -this._textLines[lineIndex - 1].length
84353     + indexOnOtherLine - textBeforeCursor.length + (1 - missingNewlineOffset);
84354  },
84355
84356  /**
84357   * for a given width it founds the matching character.
84358   * @private
84359   */
84360  _getIndexOnLine: function(lineIndex, width) {
84361
84362    var line = this._textLines[lineIndex],
84363        lineLeftOffset = this._getLineLeftOffset(lineIndex),
84364        widthOfCharsOnLine = lineLeftOffset,
84365        indexOnLine = 0, charWidth, foundMatch;
84366
84367    for (var j = 0, jlen = line.length; j < jlen; j++) {
84368      charWidth = this.__charBounds[lineIndex][j].width;
84369      widthOfCharsOnLine += charWidth;
84370      if (widthOfCharsOnLine > width) {
84371        foundMatch = true;
84372        var leftEdge = widthOfCharsOnLine - charWidth,
84373            rightEdge = widthOfCharsOnLine,
84374            offsetFromLeftEdge = Math.abs(leftEdge - width),
84375            offsetFromRightEdge = Math.abs(rightEdge - width);
84376
84377        indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1);
84378        break;
84379      }
84380    }
84381
84382    // reached end
84383    if (!foundMatch) {
84384      indexOnLine = line.length - 1;
84385    }
84386
84387    return indexOnLine;
84388  },
84389
84390
84391  /**
84392   * Moves cursor down
84393   * @param {Event} e Event object
84394   */
84395  moveCursorDown: function(e) {
84396    if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {
84397      return;
84398    }
84399    this._moveCursorUpOrDown('Down', e);
84400  },
84401
84402  /**
84403   * Moves cursor up
84404   * @param {Event} e Event object
84405   */
84406  moveCursorUp: function(e) {
84407    if (this.selectionStart === 0 && this.selectionEnd === 0) {
84408      return;
84409    }
84410    this._moveCursorUpOrDown('Up', e);
84411  },
84412
84413  /**
84414   * Moves cursor up or down, fires the events
84415   * @param {String} direction 'Up' or 'Down'
84416   * @param {Event} e Event object
84417   */
84418  _moveCursorUpOrDown: function(direction, e) {
84419    // getUpCursorOffset
84420    // getDownCursorOffset
84421    var action = 'get' + direction + 'CursorOffset',
84422        offset = this[action](e, this._selectionDirection === 'right');
84423    if (e.shiftKey) {
84424      this.moveCursorWithShift(offset);
84425    }
84426    else {
84427      this.moveCursorWithoutShift(offset);
84428    }
84429    if (offset !== 0) {
84430      this.setSelectionInBoundaries();
84431      this.abortCursorAnimation();
84432      this._currentCursorOpacity = 1;
84433      this.initDelayedCursor();
84434      this._fireSelectionChanged();
84435      this._updateTextarea();
84436    }
84437  },
84438
84439  /**
84440   * Moves cursor with shift
84441   * @param {Number} offset
84442   */
84443  moveCursorWithShift: function(offset) {
84444    var newSelection = this._selectionDirection === 'left'
84445      ? this.selectionStart + offset
84446      : this.selectionEnd + offset;
84447    this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection);
84448    return offset !== 0;
84449  },
84450
84451  /**
84452   * Moves cursor up without shift
84453   * @param {Number} offset
84454   */
84455  moveCursorWithoutShift: function(offset) {
84456    if (offset < 0) {
84457      this.selectionStart += offset;
84458      this.selectionEnd = this.selectionStart;
84459    }
84460    else {
84461      this.selectionEnd += offset;
84462      this.selectionStart = this.selectionEnd;
84463    }
84464    return offset !== 0;
84465  },
84466
84467  /**
84468   * Moves cursor left
84469   * @param {Event} e Event object
84470   */
84471  moveCursorLeft: function(e) {
84472    if (this.selectionStart === 0 && this.selectionEnd === 0) {
84473      return;
84474    }
84475    this._moveCursorLeftOrRight('Left', e);
84476  },
84477
84478  /**
84479   * @private
84480   * @return {Boolean} true if a change happened
84481   */
84482  _move: function(e, prop, direction) {
84483    var newValue;
84484    if (e.altKey) {
84485      newValue = this['findWordBoundary' + direction](this[prop]);
84486    }
84487    else if (e.metaKey || e.keyCode === 35 ||  e.keyCode === 36 ) {
84488      newValue = this['findLineBoundary' + direction](this[prop]);
84489    }
84490    else {
84491      this[prop] += direction === 'Left' ? -1 : 1;
84492      return true;
84493    }
84494    if (typeof newValue !== undefined && this[prop] !== newValue) {
84495      this[prop] = newValue;
84496      return true;
84497    }
84498  },
84499
84500  /**
84501   * @private
84502   */
84503  _moveLeft: function(e, prop) {
84504    return this._move(e, prop, 'Left');
84505  },
84506
84507  /**
84508   * @private
84509   */
84510  _moveRight: function(e, prop) {
84511    return this._move(e, prop, 'Right');
84512  },
84513
84514  /**
84515   * Moves cursor left without keeping selection
84516   * @param {Event} e
84517   */
84518  moveCursorLeftWithoutShift: function(e) {
84519    var change = true;
84520    this._selectionDirection = 'left';
84521
84522    // only move cursor when there is no selection,
84523    // otherwise we discard it, and leave cursor on same place
84524    if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) {
84525      change = this._moveLeft(e, 'selectionStart');
84526
84527    }
84528    this.selectionEnd = this.selectionStart;
84529    return change;
84530  },
84531
84532  /**
84533   * Moves cursor left while keeping selection
84534   * @param {Event} e
84535   */
84536  moveCursorLeftWithShift: function(e) {
84537    if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) {
84538      return this._moveLeft(e, 'selectionEnd');
84539    }
84540    else if (this.selectionStart !== 0){
84541      this._selectionDirection = 'left';
84542      return this._moveLeft(e, 'selectionStart');
84543    }
84544  },
84545
84546  /**
84547   * Moves cursor right
84548   * @param {Event} e Event object
84549   */
84550  moveCursorRight: function(e) {
84551    if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {
84552      return;
84553    }
84554    this._moveCursorLeftOrRight('Right', e);
84555  },
84556
84557  /**
84558   * Moves cursor right or Left, fires event
84559   * @param {String} direction 'Left', 'Right'
84560   * @param {Event} e Event object
84561   */
84562  _moveCursorLeftOrRight: function(direction, e) {
84563    var actionName = 'moveCursor' + direction + 'With';
84564    this._currentCursorOpacity = 1;
84565
84566    if (e.shiftKey) {
84567      actionName += 'Shift';
84568    }
84569    else {
84570      actionName += 'outShift';
84571    }
84572    if (this[actionName](e)) {
84573      this.abortCursorAnimation();
84574      this.initDelayedCursor();
84575      this._fireSelectionChanged();
84576      this._updateTextarea();
84577    }
84578  },
84579
84580  /**
84581   * Moves cursor right while keeping selection
84582   * @param {Event} e
84583   */
84584  moveCursorRightWithShift: function(e) {
84585    if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) {
84586      return this._moveRight(e, 'selectionStart');
84587    }
84588    else if (this.selectionEnd !== this._text.length) {
84589      this._selectionDirection = 'right';
84590      return this._moveRight(e, 'selectionEnd');
84591    }
84592  },
84593
84594  /**
84595   * Moves cursor right without keeping selection
84596   * @param {Event} e Event object
84597   */
84598  moveCursorRightWithoutShift: function(e) {
84599    var changed = true;
84600    this._selectionDirection = 'right';
84601
84602    if (this.selectionStart === this.selectionEnd) {
84603      changed = this._moveRight(e, 'selectionStart');
84604      this.selectionEnd = this.selectionStart;
84605    }
84606    else {
84607      this.selectionStart = this.selectionEnd;
84608    }
84609    return changed;
84610  },
84611
84612  /**
84613   * Removes characters from start/end
84614   * start/end ar per grapheme position in _text array.
84615   *
84616   * @param {Number} start
84617   * @param {Number} end default to start + 1
84618   */
84619  removeChars: function(start, end) {
84620    if (typeof end === 'undefined') {
84621      end = start + 1;
84622    }
84623    this.removeStyleFromTo(start, end);
84624    this._text.splice(start, end - start);
84625    this.text = this._text.join('');
84626    this.set('dirty', true);
84627    if (this._shouldClearDimensionCache()) {
84628      this.initDimensions();
84629      this.setCoords();
84630    }
84631    this._removeExtraneousStyles();
84632  },
84633
84634  /**
84635   * insert characters at start position, before start position.
84636   * start  equal 1 it means the text get inserted between actual grapheme 0 and 1
84637   * if style array is provided, it must be as the same length of text in graphemes
84638   * if end is provided and is bigger than start, old text is replaced.
84639   * start/end ar per grapheme position in _text array.
84640   *
84641   * @param {String} text text to insert
84642   * @param {Array} style array of style objects
84643   * @param {Number} start
84644   * @param {Number} end default to start + 1
84645   */
84646  insertChars: function(text, style, start, end) {
84647    if (typeof end === 'undefined') {
84648      end = start;
84649    }
84650    if (end > start) {
84651      this.removeStyleFromTo(start, end);
84652    }
84653    var graphemes = fabric.util.string.graphemeSplit(text);
84654    this.insertNewStyleBlock(graphemes, start, style);
84655    this._text = [].concat(this._text.slice(0, start), graphemes, this._text.slice(end));
84656    this.text = this._text.join('');
84657    this.set('dirty', true);
84658    if (this._shouldClearDimensionCache()) {
84659      this.initDimensions();
84660      this.setCoords();
84661    }
84662    this._removeExtraneousStyles();
84663  },
84664
84665});
84666
84667
84668/* _TO_SVG_START_ */
84669(function() {
84670  var toFixed = fabric.util.toFixed,
84671      multipleSpacesRegex = /  +/g;
84672
84673  fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ {
84674
84675    /**
84676     * Returns SVG representation of an instance
84677     * @param {Function} [reviver] Method for further parsing of svg representation.
84678     * @return {String} svg representation of an instance
84679     */
84680    _toSVG: function() {
84681      var offsets = this._getSVGLeftTopOffsets(),
84682          textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);
84683      return this._wrapSVGTextAndBg(textAndBg);
84684    },
84685
84686    /**
84687     * Returns svg representation of an instance
84688     * @param {Function} [reviver] Method for further parsing of svg representation.
84689     * @return {String} svg representation of an instance
84690     */
84691    toSVG: function(reviver) {
84692      return this._createBaseSVGMarkup(
84693        this._toSVG(),
84694        { reviver: reviver, noStyle: true, withShadow: true }
84695      );
84696    },
84697
84698    /**
84699     * @private
84700     */
84701    _getSVGLeftTopOffsets: function() {
84702      return {
84703        textLeft: -this.width / 2,
84704        textTop: -this.height / 2,
84705        lineTop: this.getHeightOfLine(0)
84706      };
84707    },
84708
84709    /**
84710     * @private
84711     */
84712    _wrapSVGTextAndBg: function(textAndBg) {
84713      var noShadow = true,
84714          textDecoration = this.getSvgTextDecoration(this);
84715      return [
84716        textAndBg.textBgRects.join(''),
84717        '\t\t<text xml:space="preserve" ',
84718        (this.fontFamily ? 'font-family="' + this.fontFamily.replace(/"/g, '\'') + '" ' : ''),
84719        (this.fontSize ? 'font-size="' + this.fontSize + '" ' : ''),
84720        (this.fontStyle ? 'font-style="' + this.fontStyle + '" ' : ''),
84721        (this.fontWeight ? 'font-weight="' + this.fontWeight + '" ' : ''),
84722        (textDecoration ? 'text-decoration="' + textDecoration + '" ' : ''),
84723        'style="', this.getSvgStyles(noShadow), '"', this.addPaintOrder(), ' >',
84724        textAndBg.textSpans.join(''),
84725        '</text>\n'
84726      ];
84727    },
84728
84729    /**
84730     * @private
84731     * @param {Number} textTopOffset Text top offset
84732     * @param {Number} textLeftOffset Text left offset
84733     * @return {Object}
84734     */
84735    _getSVGTextAndBg: function(textTopOffset, textLeftOffset) {
84736      var textSpans = [],
84737          textBgRects = [],
84738          height = textTopOffset, lineOffset;
84739      // bounding-box background
84740      this._setSVGBg(textBgRects);
84741
84742      // text and text-background
84743      for (var i = 0, len = this._textLines.length; i < len; i++) {
84744        lineOffset = this._getLineLeftOffset(i);
84745        if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {
84746          this._setSVGTextLineBg(textBgRects, i, textLeftOffset + lineOffset, height);
84747        }
84748        this._setSVGTextLineText(textSpans, i, textLeftOffset + lineOffset, height);
84749        height += this.getHeightOfLine(i);
84750      }
84751
84752      return {
84753        textSpans: textSpans,
84754        textBgRects: textBgRects
84755      };
84756    },
84757
84758    /**
84759     * @private
84760     */
84761    _createTextCharSpan: function(_char, styleDecl, left, top) {
84762      var shouldUseWhitespace = _char !== _char.trim() || _char.match(multipleSpacesRegex),
84763          styleProps = this.getSvgSpanStyles(styleDecl, shouldUseWhitespace),
84764          fillStyles = styleProps ? 'style="' + styleProps + '"' : '',
84765          dy = styleDecl.deltaY, dySpan = '',
84766          NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;
84767      if (dy) {
84768        dySpan = ' dy="' + toFixed(dy, NUM_FRACTION_DIGITS) + '" ';
84769      }
84770      return [
84771        '<tspan x="', toFixed(left, NUM_FRACTION_DIGITS), '" y="',
84772        toFixed(top, NUM_FRACTION_DIGITS), '" ', dySpan,
84773        fillStyles, '>',
84774        fabric.util.string.escapeXml(_char),
84775        '</tspan>'
84776      ].join('');
84777    },
84778
84779    _setSVGTextLineText: function(textSpans, lineIndex, textLeftOffset, textTopOffset) {
84780      // set proper line offset
84781      var lineHeight = this.getHeightOfLine(lineIndex),
84782          isJustify = this.textAlign.indexOf('justify') !== -1,
84783          actualStyle,
84784          nextStyle,
84785          charsToRender = '',
84786          charBox, style,
84787          boxWidth = 0,
84788          line = this._textLines[lineIndex],
84789          timeToRender;
84790
84791      textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight;
84792      for (var i = 0, len = line.length - 1; i <= len; i++) {
84793        timeToRender = i === len || this.charSpacing;
84794        charsToRender += line[i];
84795        charBox = this.__charBounds[lineIndex][i];
84796        if (boxWidth === 0) {
84797          textLeftOffset += charBox.kernedWidth - charBox.width;
84798          boxWidth += charBox.width;
84799        }
84800        else {
84801          boxWidth += charBox.kernedWidth;
84802        }
84803        if (isJustify && !timeToRender) {
84804          if (this._reSpaceAndTab.test(line[i])) {
84805            timeToRender = true;
84806          }
84807        }
84808        if (!timeToRender) {
84809          // if we have charSpacing, we render char by char
84810          actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);
84811          nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);
84812          timeToRender = this._hasStyleChangedForSvg(actualStyle, nextStyle);
84813        }
84814        if (timeToRender) {
84815          style = this._getStyleDeclaration(lineIndex, i) || { };
84816          textSpans.push(this._createTextCharSpan(charsToRender, style, textLeftOffset, textTopOffset));
84817          charsToRender = '';
84818          actualStyle = nextStyle;
84819          textLeftOffset += boxWidth;
84820          boxWidth = 0;
84821        }
84822      }
84823    },
84824
84825    _pushTextBgRect: function(textBgRects, color, left, top, width, height) {
84826      var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;
84827      textBgRects.push(
84828        '\t\t<rect ',
84829        this._getFillAttributes(color),
84830        ' x="',
84831        toFixed(left, NUM_FRACTION_DIGITS),
84832        '" y="',
84833        toFixed(top, NUM_FRACTION_DIGITS),
84834        '" width="',
84835        toFixed(width, NUM_FRACTION_DIGITS),
84836        '" height="',
84837        toFixed(height, NUM_FRACTION_DIGITS),
84838        '"></rect>\n');
84839    },
84840
84841    _setSVGTextLineBg: function(textBgRects, i, leftOffset, textTopOffset) {
84842      var line = this._textLines[i],
84843          heightOfLine = this.getHeightOfLine(i) / this.lineHeight,
84844          boxWidth = 0,
84845          boxStart = 0,
84846          charBox, currentColor,
84847          lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');
84848      for (var j = 0, jlen = line.length; j < jlen; j++) {
84849        charBox = this.__charBounds[i][j];
84850        currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');
84851        if (currentColor !== lastColor) {
84852          lastColor && this._pushTextBgRect(textBgRects, lastColor, leftOffset + boxStart,
84853            textTopOffset, boxWidth, heightOfLine);
84854          boxStart = charBox.left;
84855          boxWidth = charBox.width;
84856          lastColor = currentColor;
84857        }
84858        else {
84859          boxWidth += charBox.kernedWidth;
84860        }
84861      }
84862      currentColor && this._pushTextBgRect(textBgRects, currentColor, leftOffset + boxStart,
84863        textTopOffset, boxWidth, heightOfLine);
84864    },
84865
84866    /**
84867     * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values
84868     * we work around it by "moving" alpha channel into opacity attribute and setting fill's alpha to 1
84869     *
84870     * @private
84871     * @param {*} value
84872     * @return {String}
84873     */
84874    _getFillAttributes: function(value) {
84875      var fillColor = (value && typeof value === 'string') ? new fabric.Color(value) : '';
84876      if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) {
84877        return 'fill="' + value + '"';
84878      }
84879      return 'opacity="' + fillColor.getAlpha() + '" fill="' + fillColor.setAlpha(1).toRgb() + '"';
84880    },
84881
84882    /**
84883     * @private
84884     */
84885    _getSVGLineTopOffset: function(lineIndex) {
84886      var lineTopOffset = 0, lastHeight = 0;
84887      for (var j = 0; j < lineIndex; j++) {
84888        lineTopOffset += this.getHeightOfLine(j);
84889      }
84890      lastHeight = this.getHeightOfLine(j);
84891      return {
84892        lineTop: lineTopOffset,
84893        offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)
84894      };
84895    },
84896
84897    /**
84898     * Returns styles-string for svg-export
84899     * @param {Boolean} skipShadow a boolean to skip shadow filter output
84900     * @return {String}
84901     */
84902    getSvgStyles: function(skipShadow) {
84903      var svgStyle = fabric.Object.prototype.getSvgStyles.call(this, skipShadow);
84904      return svgStyle + ' white-space: pre;';
84905    },
84906  });
84907})();
84908/* _TO_SVG_END_ */
84909
84910
84911(function(global) {
84912
84913  'use strict';
84914
84915  var fabric = global.fabric || (global.fabric = {});
84916
84917  /**
84918   * Textbox class, based on IText, allows the user to resize the text rectangle
84919   * and wraps lines automatically. Textboxes have their Y scaling locked, the
84920   * user can only change width. Height is adjusted automatically based on the
84921   * wrapping of lines.
84922   * @class fabric.Textbox
84923   * @extends fabric.IText
84924   * @mixes fabric.Observable
84925   * @return {fabric.Textbox} thisArg
84926   * @see {@link fabric.Textbox#initialize} for constructor definition
84927   */
84928  fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, {
84929
84930    /**
84931     * Type of an object
84932     * @type String
84933     * @default
84934     */
84935    type: 'textbox',
84936
84937    /**
84938     * Minimum width of textbox, in pixels.
84939     * @type Number
84940     * @default
84941     */
84942    minWidth: 20,
84943
84944    /**
84945     * Minimum calculated width of a textbox, in pixels.
84946     * fixed to 2 so that an empty textbox cannot go to 0
84947     * and is still selectable without text.
84948     * @type Number
84949     * @default
84950     */
84951    dynamicMinWidth: 2,
84952
84953    /**
84954     * Cached array of text wrapping.
84955     * @type Array
84956     */
84957    __cachedLines: null,
84958
84959    /**
84960     * Override standard Object class values
84961     */
84962    lockScalingFlip: true,
84963
84964    /**
84965     * Override standard Object class values
84966     * Textbox needs this on false
84967     */
84968    noScaleCache: false,
84969
84970    /**
84971     * Properties which when set cause object to change dimensions
84972     * @type Object
84973     * @private
84974     */
84975    _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat('width'),
84976
84977    /**
84978     * Use this regular expression to split strings in breakable lines
84979     * @private
84980     */
84981    _wordJoiners: /[ \t\r]/,
84982
84983    /**
84984     * Use this boolean property in order to split strings that have no white space concept.
84985     * this is a cheap way to help with chinese/japanese
84986     * @type Boolean
84987     * @since 2.6.0
84988     */
84989    splitByGrapheme: false,
84990
84991    /**
84992     * Unlike superclass's version of this function, Textbox does not update
84993     * its width.
84994     * @private
84995     * @override
84996     */
84997    initDimensions: function() {
84998      if (this.__skipDimension) {
84999        return;
85000      }
85001      this.isEditing && this.initDelayedCursor();
85002      this.clearContextTop();
85003      this._clearCache();
85004      // clear dynamicMinWidth as it will be different after we re-wrap line
85005      this.dynamicMinWidth = 0;
85006      // wrap lines
85007      this._styleMap = this._generateStyleMap(this._splitText());
85008      // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap
85009      if (this.dynamicMinWidth > this.width) {
85010        this._set('width', this.dynamicMinWidth);
85011      }
85012      if (this.textAlign.indexOf('justify') !== -1) {
85013        // once text is measured we need to make space fatter to make justified text.
85014        this.enlargeSpaces();
85015      }
85016      // clear cache and re-calculate height
85017      this.height = this.calcTextHeight();
85018      this.saveState({ propertySet: '_dimensionAffectingProps' });
85019    },
85020
85021    /**
85022     * Generate an object that translates the style object so that it is
85023     * broken up by visual lines (new lines and automatic wrapping).
85024     * The original text styles object is broken up by actual lines (new lines only),
85025     * which is only sufficient for Text / IText
85026     * @private
85027     */
85028    _generateStyleMap: function(textInfo) {
85029      var realLineCount     = 0,
85030          realLineCharCount = 0,
85031          charCount         = 0,
85032          map               = {};
85033
85034      for (var i = 0; i < textInfo.graphemeLines.length; i++) {
85035        if (textInfo.graphemeText[charCount] === '\n' && i > 0) {
85036          realLineCharCount = 0;
85037          charCount++;
85038          realLineCount++;
85039        }
85040        else if (!this.splitByGrapheme && this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) && i > 0) {
85041          // this case deals with space's that are removed from end of lines when wrapping
85042          realLineCharCount++;
85043          charCount++;
85044        }
85045
85046        map[i] = { line: realLineCount, offset: realLineCharCount };
85047
85048        charCount += textInfo.graphemeLines[i].length;
85049        realLineCharCount += textInfo.graphemeLines[i].length;
85050      }
85051
85052      return map;
85053    },
85054
85055    /**
85056     * Returns true if object has a style property or has it on a specified line
85057     * @param {Number} lineIndex
85058     * @return {Boolean}
85059     */
85060    styleHas: function(property, lineIndex) {
85061      if (this._styleMap && !this.isWrapping) {
85062        var map = this._styleMap[lineIndex];
85063        if (map) {
85064          lineIndex = map.line;
85065        }
85066      }
85067      return fabric.Text.prototype.styleHas.call(this, property, lineIndex);
85068    },
85069
85070    /**
85071     * Returns true if object has no styling or no styling in a line
85072     * @param {Number} lineIndex , lineIndex is on wrapped lines.
85073     * @return {Boolean}
85074     */
85075    isEmptyStyles: function(lineIndex) {
85076      if (!this.styles) {
85077        return true;
85078      }
85079      var offset = 0, nextLineIndex = lineIndex + 1, nextOffset, obj, shouldLimit = false,
85080          map = this._styleMap[lineIndex], mapNextLine = this._styleMap[lineIndex + 1];
85081      if (map) {
85082        lineIndex = map.line;
85083        offset = map.offset;
85084      }
85085      if (mapNextLine) {
85086        nextLineIndex = mapNextLine.line;
85087        shouldLimit = nextLineIndex === lineIndex;
85088        nextOffset = mapNextLine.offset;
85089      }
85090      obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] };
85091      for (var p1 in obj) {
85092        for (var p2 in obj[p1]) {
85093          if (p2 >= offset && (!shouldLimit || p2 < nextOffset)) {
85094            // eslint-disable-next-line no-unused-vars
85095            for (var p3 in obj[p1][p2]) {
85096              return false;
85097            }
85098          }
85099        }
85100      }
85101      return true;
85102    },
85103
85104    /**
85105     * @param {Number} lineIndex
85106     * @param {Number} charIndex
85107     * @private
85108     */
85109    _getStyleDeclaration: function(lineIndex, charIndex) {
85110      if (this._styleMap && !this.isWrapping) {
85111        var map = this._styleMap[lineIndex];
85112        if (!map) {
85113          return null;
85114        }
85115        lineIndex = map.line;
85116        charIndex = map.offset + charIndex;
85117      }
85118      return this.callSuper('_getStyleDeclaration', lineIndex, charIndex);
85119    },
85120
85121    /**
85122     * @param {Number} lineIndex
85123     * @param {Number} charIndex
85124     * @param {Object} style
85125     * @private
85126     */
85127    _setStyleDeclaration: function(lineIndex, charIndex, style) {
85128      var map = this._styleMap[lineIndex];
85129      lineIndex = map.line;
85130      charIndex = map.offset + charIndex;
85131
85132      this.styles[lineIndex][charIndex] = style;
85133    },
85134
85135    /**
85136     * @param {Number} lineIndex
85137     * @param {Number} charIndex
85138     * @private
85139     */
85140    _deleteStyleDeclaration: function(lineIndex, charIndex) {
85141      var map = this._styleMap[lineIndex];
85142      lineIndex = map.line;
85143      charIndex = map.offset + charIndex;
85144      delete this.styles[lineIndex][charIndex];
85145    },
85146
85147    /**
85148     * probably broken need a fix
85149     * Returns the real style line that correspond to the wrapped lineIndex line
85150     * Used just to verify if the line does exist or not.
85151     * @param {Number} lineIndex
85152     * @returns {Boolean} if the line exists or not
85153     * @private
85154     */
85155    _getLineStyle: function(lineIndex) {
85156      var map = this._styleMap[lineIndex];
85157      return !!this.styles[map.line];
85158    },
85159
85160    /**
85161     * Set the line style to an empty object so that is initialized
85162     * @param {Number} lineIndex
85163     * @param {Object} style
85164     * @private
85165     */
85166    _setLineStyle: function(lineIndex) {
85167      var map = this._styleMap[lineIndex];
85168      this.styles[map.line] = {};
85169    },
85170
85171    /**
85172     * Wraps text using the 'width' property of Textbox. First this function
85173     * splits text on newlines, so we preserve newlines entered by the user.
85174     * Then it wraps each line using the width of the Textbox by calling
85175     * _wrapLine().
85176     * @param {Array} lines The string array of text that is split into lines
85177     * @param {Number} desiredWidth width you want to wrap to
85178     * @returns {Array} Array of lines
85179     */
85180    _wrapText: function(lines, desiredWidth) {
85181      var wrapped = [], i;
85182      this.isWrapping = true;
85183      for (i = 0; i < lines.length; i++) {
85184        wrapped = wrapped.concat(this._wrapLine(lines[i], i, desiredWidth));
85185      }
85186      this.isWrapping = false;
85187      return wrapped;
85188    },
85189
85190    /**
85191     * Helper function to measure a string of text, given its lineIndex and charIndex offset
85192     * it gets called when charBounds are not available yet.
85193     * @param {CanvasRenderingContext2D} ctx
85194     * @param {String} text
85195     * @param {number} lineIndex
85196     * @param {number} charOffset
85197     * @returns {number}
85198     * @private
85199     */
85200    _measureWord: function(word, lineIndex, charOffset) {
85201      var width = 0, prevGrapheme, skipLeft = true;
85202      charOffset = charOffset || 0;
85203      for (var i = 0, len = word.length; i < len; i++) {
85204        var box = this._getGraphemeBox(word[i], lineIndex, i + charOffset, prevGrapheme, skipLeft);
85205        width += box.kernedWidth;
85206        prevGrapheme = word[i];
85207      }
85208      return width;
85209    },
85210
85211    /**
85212     * Wraps a line of text using the width of the Textbox and a context.
85213     * @param {Array} line The grapheme array that represent the line
85214     * @param {Number} lineIndex
85215     * @param {Number} desiredWidth width you want to wrap the line to
85216     * @param {Number} reservedSpace space to remove from wrapping for custom functionalities
85217     * @returns {Array} Array of line(s) into which the given text is wrapped
85218     * to.
85219     */
85220    _wrapLine: function(_line, lineIndex, desiredWidth, reservedSpace) {
85221      var lineWidth = 0,
85222          splitByGrapheme = this.splitByGrapheme,
85223          graphemeLines = [],
85224          line = [],
85225          // spaces in different languages?
85226          words = splitByGrapheme ? fabric.util.string.graphemeSplit(_line) : _line.split(this._wordJoiners),
85227          word = '',
85228          offset = 0,
85229          infix = splitByGrapheme ? '' : ' ',
85230          wordWidth = 0,
85231          infixWidth = 0,
85232          largestWordWidth = 0,
85233          lineJustStarted = true,
85234          additionalSpace = this._getWidthOfCharSpacing(),
85235          reservedSpace = reservedSpace || 0;
85236      // fix a difference between split and graphemeSplit
85237      if (words.length === 0) {
85238        words.push([]);
85239      }
85240      desiredWidth -= reservedSpace;
85241      for (var i = 0; i < words.length; i++) {
85242        // if using splitByGrapheme words are already in graphemes.
85243        word = splitByGrapheme ? words[i] : fabric.util.string.graphemeSplit(words[i]);
85244        wordWidth = this._measureWord(word, lineIndex, offset);
85245        offset += word.length;
85246
85247        lineWidth += infixWidth + wordWidth - additionalSpace;
85248        if (lineWidth > desiredWidth && !lineJustStarted) {
85249          graphemeLines.push(line);
85250          line = [];
85251          lineWidth = wordWidth;
85252          lineJustStarted = true;
85253        }
85254        else {
85255          lineWidth += additionalSpace;
85256        }
85257
85258        if (!lineJustStarted && !splitByGrapheme) {
85259          line.push(infix);
85260        }
85261        line = line.concat(word);
85262
85263        infixWidth = splitByGrapheme ? 0 : this._measureWord([infix], lineIndex, offset);
85264        offset++;
85265        lineJustStarted = false;
85266        // keep track of largest word
85267        if (wordWidth > largestWordWidth) {
85268          largestWordWidth = wordWidth;
85269        }
85270      }
85271
85272      i && graphemeLines.push(line);
85273
85274      if (largestWordWidth + reservedSpace > this.dynamicMinWidth) {
85275        this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace;
85276      }
85277      return graphemeLines;
85278    },
85279
85280    /**
85281     * Detect if the text line is ended with an hard break
85282     * text and itext do not have wrapping, return false
85283     * @param {Number} lineIndex text to split
85284     * @return {Boolean}
85285     */
85286    isEndOfWrapping: function(lineIndex) {
85287      if (!this._styleMap[lineIndex + 1]) {
85288        // is last line, return true;
85289        return true;
85290      }
85291      if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) {
85292        // this is last line before a line break, return true;
85293        return true;
85294      }
85295      return false;
85296    },
85297
85298    /**
85299     * Detect if a line has a linebreak and so we need to account for it when moving
85300     * and counting style.
85301     * @return Number
85302     */
85303    missingNewlineOffset: function(lineIndex) {
85304      if (this.splitByGrapheme) {
85305        return this.isEndOfWrapping(lineIndex) ? 1 : 0;
85306      }
85307      return 1;
85308    },
85309
85310    /**
85311    * Gets lines of text to render in the Textbox. This function calculates
85312    * text wrapping on the fly every time it is called.
85313    * @param {String} text text to split
85314    * @returns {Array} Array of lines in the Textbox.
85315    * @override
85316    */
85317    _splitTextIntoLines: function(text) {
85318      var newText = fabric.Text.prototype._splitTextIntoLines.call(this, text),
85319          graphemeLines = this._wrapText(newText.lines, this.width),
85320          lines = new Array(graphemeLines.length);
85321      for (var i = 0; i < graphemeLines.length; i++) {
85322        lines[i] = graphemeLines[i].join('');
85323      }
85324      newText.lines = lines;
85325      newText.graphemeLines = graphemeLines;
85326      return newText;
85327    },
85328
85329    getMinWidth: function() {
85330      return Math.max(this.minWidth, this.dynamicMinWidth);
85331    },
85332
85333    _removeExtraneousStyles: function() {
85334      var linesToKeep = {};
85335      for (var prop in this._styleMap) {
85336        if (this._textLines[prop]) {
85337          linesToKeep[this._styleMap[prop].line] = 1;
85338        }
85339      }
85340      for (var prop in this.styles) {
85341        if (!linesToKeep[prop]) {
85342          delete this.styles[prop];
85343        }
85344      }
85345    },
85346
85347    /**
85348     * Returns object representation of an instance
85349     * @method toObject
85350     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
85351     * @return {Object} object representation of an instance
85352     */
85353    toObject: function(propertiesToInclude) {
85354      return this.callSuper('toObject', ['minWidth', 'splitByGrapheme'].concat(propertiesToInclude));
85355    }
85356  });
85357
85358  /**
85359   * Returns fabric.Textbox instance from an object representation
85360   * @static
85361   * @memberOf fabric.Textbox
85362   * @param {Object} object Object to create an instance from
85363   * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created
85364   */
85365  fabric.Textbox.fromObject = function(object, callback) {
85366    return fabric.Object._fromObject('Textbox', object, callback, 'text');
85367  };
85368})( true ? exports : 
vendor: 2,575 bytes, lines 85368-85457
85368this);
85369
85370
85371(function() {
85372
85373  var controlsUtils = fabric.controlsUtils,
85374      scaleSkewStyleHandler = controlsUtils.scaleSkewCursorStyleHandler,
85375      scaleStyleHandler = controlsUtils.scaleCursorStyleHandler,
85376      scalingEqually = controlsUtils.scalingEqually,
85377      scalingYOrSkewingX = controlsUtils.scalingYOrSkewingX,
85378      scalingXOrSkewingY = controlsUtils.scalingXOrSkewingY,
85379      scaleOrSkewActionName = controlsUtils.scaleOrSkewActionName,
85380      objectControls = fabric.Object.prototype.controls;
85381
85382  objectControls.ml = new fabric.Control({
85383    x: -0.5,
85384    y: 0,
85385    cursorStyleHandler: scaleSkewStyleHandler,
85386    actionHandler: scalingXOrSkewingY,
85387    getActionName: scaleOrSkewActionName,
85388  });
85389
85390  objectControls.mr = new fabric.Control({
85391    x: 0.5,
85392    y: 0,
85393    cursorStyleHandler: scaleSkewStyleHandler,
85394    actionHandler: scalingXOrSkewingY,
85395    getActionName: scaleOrSkewActionName,
85396  });
85397
85398  objectControls.mb = new fabric.Control({
85399    x: 0,
85400    y: 0.5,
85401    cursorStyleHandler: scaleSkewStyleHandler,
85402    actionHandler: scalingYOrSkewingX,
85403    getActionName: scaleOrSkewActionName,
85404  });
85405
85406  objectControls.mt = new fabric.Control({
85407    x: 0,
85408    y: -0.5,
85409    cursorStyleHandler: scaleSkewStyleHandler,
85410    actionHandler: scalingYOrSkewingX,
85411    getActionName: scaleOrSkewActionName,
85412  });
85413
85414  objectControls.tl = new fabric.Control({
85415    x: -0.5,
85416    y: -0.5,
85417    cursorStyleHandler: scaleStyleHandler,
85418    actionHandler: scalingEqually
85419  });
85420
85421  objectControls.tr = new fabric.Control({
85422    x: 0.5,
85423    y: -0.5,
85424    cursorStyleHandler: scaleStyleHandler,
85425    actionHandler: scalingEqually
85426  });
85427
85428  objectControls.bl = new fabric.Control({
85429    x: -0.5,
85430    y: 0.5,
85431    cursorStyleHandler: scaleStyleHandler,
85432    actionHandler: scalingEqually
85433  });
85434
85435  objectControls.br = new fabric.Control({
85436    x: 0.5,
85437    y: 0.5,
85438    cursorStyleHandler: scaleStyleHandler,
85439    actionHandler: scalingEqually
85440  });
85441
85442  objectControls.mtr = new fabric.Control({
85443    x: 0,
85444    y: -0.5,
85445    actionHandler: controlsUtils.rotationWithSnapping,
85446    cursorStyleHandler: controlsUtils.rotationStyleHandler,
85447    offsetY: -40,
85448    withConnection: true,
85449    actionName: 'rotate',
85450  });
85451
85452  if (fabric.Textbox) {
85453    // this is breaking the prototype inheritance, no time / ideas to fix it.
85454    // is important to document that if you want to have all objects to have a
85455    // specific custom control, you have to add it to Object prototype and to Textbox
85456    // prototype. The controls are shared as references. So changes to control `tr`
85457    // can still apply to all objects if needed.
85458    var textBoxControls = fabric.Textbox.prototype.controls = { };
85459
85460    textBoxControls.mtr = objectControls.mtr;
85461    textBoxControls.tr = objectControls.tr;
85462    textBoxControls.br = objectControls.br;
85463    textBoxControls.tl = objectControls.tl;
85464    textBoxControls.bl = objectControls.bl;
85465    textBoxControls.mt = objectControls.mt;
85466    textBoxControls.mb = objectControls.mb;
85467
85468    textBoxControls.mr = new fabric.Control({
85469      x: 0.5,
85470      y: 0,
85471      actionHandler: controlsUtils.changeWidth,
85472      cursorStyleHandler: scaleSkewStyleHandler,
85473      actionName: 'resizing',
85474    });
85475
85476    textBoxControls.ml = new fabric.Control({
85477      x: -0.5,
85478      y: 0,
85479      actionHandler: controlsUtils.changeWidth,
85480      cursorStyleHandler: scaleSkewStyleHandler,
85481      actionName: 'resizing',
85482    });
85483  }
85484})();
85485
85486
85487/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(256).Buffer))
85488
85489/***/ }),
85490/* 256 */
85491/***/ (function(module, exports, __webpack_require__) {
85492
85493"use strict";
85494/* WEBPACK VAR INJECTION */(function(global) {/*!
85495 * The buffer module from node.js, for the browser.
85496 *
85497 * @author   Feross Aboukhadijeh <http://feross.org>
85498 * @license  MIT
85499 */
85500/* eslint-disable no-proto */
85501
85502
85503
85504var base64 = __webpack_require__(258)
85505var ieee754 = __webpack_require__(259)
85506var isArray = __webpack_require__(260
vendor: 48,349 bytes, lines 85506-87284
85506)
85507
85508exports.Buffer = Buffer
85509exports.SlowBuffer = SlowBuffer
85510exports.INSPECT_MAX_BYTES = 50
85511
85512/**
85513 * If `Buffer.TYPED_ARRAY_SUPPORT`:
85514 *   === true    Use Uint8Array implementation (fastest)
85515 *   === false   Use Object implementation (most compatible, even IE6)
85516 *
85517 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
85518 * Opera 11.6+, iOS 4.2+.
85519 *
85520 * Due to various browser bugs, sometimes the Object implementation will be used even
85521 * when the browser supports typed arrays.
85522 *
85523 * Note:
85524 *
85525 *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
85526 *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
85527 *
85528 *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
85529 *
85530 *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
85531 *     incorrect length in some situations.
85532
85533 * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
85534 * get the Object implementation, which is slower but behaves correctly.
85535 */
85536Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
85537  ? global.TYPED_ARRAY_SUPPORT
85538  : typedArraySupport()
85539
85540/*
85541 * Export kMaxLength after typed array support is determined.
85542 */
85543exports.kMaxLength = kMaxLength()
85544
85545function typedArraySupport () {
85546  try {
85547    var arr = new Uint8Array(1)
85548    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
85549    return arr.foo() === 42 && // typed array instances can be augmented
85550        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
85551        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
85552  } catch (e) {
85553    return false
85554  }
85555}
85556
85557function kMaxLength () {
85558  return Buffer.TYPED_ARRAY_SUPPORT
85559    ? 0x7fffffff
85560    : 0x3fffffff
85561}
85562
85563function createBuffer (that, length) {
85564  if (kMaxLength() < length) {
85565    throw new RangeError('Invalid typed array length')
85566  }
85567  if (Buffer.TYPED_ARRAY_SUPPORT) {
85568    // Return an augmented `Uint8Array` instance, for best performance
85569    that = new Uint8Array(length)
85570    that.__proto__ = Buffer.prototype
85571  } else {
85572    // Fallback: Return an object instance of the Buffer class
85573    if (that === null) {
85574      that = new Buffer(length)
85575    }
85576    that.length = length
85577  }
85578
85579  return that
85580}
85581
85582/**
85583 * The Buffer constructor returns instances of `Uint8Array` that have their
85584 * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
85585 * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
85586 * and the `Uint8Array` methods. Square bracket notation works as expected -- it
85587 * returns a single octet.
85588 *
85589 * The `Uint8Array` prototype remains unmodified.
85590 */
85591
85592function Buffer (arg, encodingOrOffset, length) {
85593  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
85594    return new Buffer(arg, encodingOrOffset, length)
85595  }
85596
85597  // Common case.
85598  if (typeof arg === 'number') {
85599    if (typeof encodingOrOffset === 'string') {
85600      throw new Error(
85601        'If encoding is specified then the first argument must be a string'
85602      )
85603    }
85604    return allocUnsafe(this, arg)
85605  }
85606  return from(this, arg, encodingOrOffset, length)
85607}
85608
85609Buffer.poolSize = 8192 // not used by this implementation
85610
85611// TODO: Legacy, not needed anymore. Remove in next major version.
85612Buffer._augment = function (arr) {
85613  arr.__proto__ = Buffer.prototype
85614  return arr
85615}
85616
85617function from (that, value, encodingOrOffset, length) {
85618  if (typeof value === 'number') {
85619    throw new TypeError('"value" argument must not be a number')
85620  }
85621
85622  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
85623    return fromArrayBuffer(that, value, encodingOrOffset, length)
85624  }
85625
85626  if (typeof value === 'string') {
85627    return fromString(that, value, encodingOrOffset)
85628  }
85629
85630  return fromObject(that, value)
85631}
85632
85633/**
85634 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
85635 * if value is a number.
85636 * Buffer.from(str[, encoding])
85637 * Buffer.from(array)
85638 * Buffer.from(buffer)
85639 * Buffer.from(arrayBuffer[, byteOffset[, length]])
85640 **/
85641Buffer.from = function (value, encodingOrOffset, length) {
85642  return from(null, value, encodingOrOffset, length)
85643}
85644
85645if (Buffer.TYPED_ARRAY_SUPPORT) {
85646  Buffer.prototype.__proto__ = Uint8Array.prototype
85647  Buffer.__proto__ = Uint8Array
85648  if (typeof Symbol !== 'undefined' && Symbol.species &&
85649      Buffer[Symbol.species] === Buffer) {
85650    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
85651    Object.defineProperty(Buffer, Symbol.species, {
85652      value: null,
85653      configurable: true
85654    })
85655  }
85656}
85657
85658function assertSize (size) {
85659  if (typeof size !== 'number') {
85660    throw new TypeError('"size" argument must be a number')
85661  } else if (size < 0) {
85662    throw new RangeError('"size" argument must not be negative')
85663  }
85664}
85665
85666function alloc (that, size, fill, encoding) {
85667  assertSize(size)
85668  if (size <= 0) {
85669    return createBuffer(that, size)
85670  }
85671  if (fill !== undefined) {
85672    // Only pay attention to encoding if it's a string. This
85673    // prevents accidentally sending in a number that would
85674    // be interpretted as a start offset.
85675    return typeof encoding === 'string'
85676      ? createBuffer(that, size).fill(fill, encoding)
85677      : createBuffer(that, size).fill(fill)
85678  }
85679  return createBuffer(that, size)
85680}
85681
85682/**
85683 * Creates a new filled Buffer instance.
85684 * alloc(size[, fill[, encoding]])
85685 **/
85686Buffer.alloc = function (size, fill, encoding) {
85687  return alloc(null, size, fill, encoding)
85688}
85689
85690function allocUnsafe (that, size) {
85691  assertSize(size)
85692  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
85693  if (!Buffer.TYPED_ARRAY_SUPPORT) {
85694    for (var i = 0; i < size; ++i) {
85695      that[i] = 0
85696    }
85697  }
85698  return that
85699}
85700
85701/**
85702 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
85703 * */
85704Buffer.allocUnsafe = function (size) {
85705  return allocUnsafe(null, size)
85706}
85707/**
85708 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
85709 */
85710Buffer.allocUnsafeSlow = function (size) {
85711  return allocUnsafe(null, size)
85712}
85713
85714function fromString (that, string, encoding) {
85715  if (typeof encoding !== 'string' || encoding === '') {
85716    encoding = 'utf8'
85717  }
85718
85719  if (!Buffer.isEncoding(encoding)) {
85720    throw new TypeError('"encoding" must be a valid string encoding')
85721  }
85722
85723  var length = byteLength(string, encoding) | 0
85724  that = createBuffer(that, length)
85725
85726  var actual = that.write(string, encoding)
85727
85728  if (actual !== length) {
85729    // Writing a hex string, for example, that contains invalid characters will
85730    // cause everything after the first invalid character to be ignored. (e.g.
85731    // 'abxxcd' will be treated as 'ab')
85732    that = that.slice(0, actual)
85733  }
85734
85735  return that
85736}
85737
85738function fromArrayLike (that, array) {
85739  var length = array.length < 0 ? 0 : checked(array.length) | 0
85740  that = createBuffer(that, length)
85741  for (var i = 0; i < length; i += 1) {
85742    that[i] = array[i] & 255
85743  }
85744  return that
85745}
85746
85747function fromArrayBuffer (that, array, byteOffset, length) {
85748  array.byteLength // this throws if `array` is not a valid ArrayBuffer
85749
85750  if (byteOffset < 0 || array.byteLength < byteOffset) {
85751    throw new RangeError('\'offset\' is out of bounds')
85752  }
85753
85754  if (array.byteLength < byteOffset + (length || 0)) {
85755    throw new RangeError('\'length\' is out of bounds')
85756  }
85757
85758  if (byteOffset === undefined && length === undefined) {
85759    array = new Uint8Array(array)
85760  } else if (length === undefined) {
85761    array = new Uint8Array(array, byteOffset)
85762  } else {
85763    array = new Uint8Array(array, byteOffset, length)
85764  }
85765
85766  if (Buffer.TYPED_ARRAY_SUPPORT) {
85767    // Return an augmented `Uint8Array` instance, for best performance
85768    that = array
85769    that.__proto__ = Buffer.prototype
85770  } else {
85771    // Fallback: Return an object instance of the Buffer class
85772    that = fromArrayLike(that, array)
85773  }
85774  return that
85775}
85776
85777function fromObject (that, obj) {
85778  if (Buffer.isBuffer(obj)) {
85779    var len = checked(obj.length) | 0
85780    that = createBuffer(that, len)
85781
85782    if (that.length === 0) {
85783      return that
85784    }
85785
85786    obj.copy(that, 0, 0, len)
85787    return that
85788  }
85789
85790  if (obj) {
85791    if ((typeof ArrayBuffer !== 'undefined' &&
85792        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
85793      if (typeof obj.length !== 'number' || isnan(obj.length)) {
85794        return createBuffer(that, 0)
85795      }
85796      return fromArrayLike(that, obj)
85797    }
85798
85799    if (obj.type === 'Buffer' && isArray(obj.data)) {
85800      return fromArrayLike(that, obj.data)
85801    }
85802  }
85803
85804  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
85805}
85806
85807function checked (length) {
85808  // Note: cannot use `length < kMaxLength()` here because that fails when
85809  // length is NaN (which is otherwise coerced to zero.)
85810  if (length >= kMaxLength()) {
85811    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
85812                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
85813  }
85814  return length | 0
85815}
85816
85817function SlowBuffer (length) {
85818  if (+length != length) { // eslint-disable-line eqeqeq
85819    length = 0
85820  }
85821  return Buffer.alloc(+length)
85822}
85823
85824Buffer.isBuffer = function isBuffer (b) {
85825  return !!(b != null && b._isBuffer)
85826}
85827
85828Buffer.compare = function compare (a, b) {
85829  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
85830    throw new TypeError('Arguments must be Buffers')
85831  }
85832
85833  if (a === b) return 0
85834
85835  var x = a.length
85836  var y = b.length
85837
85838  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
85839    if (a[i] !== b[i]) {
85840      x = a[i]
85841      y = b[i]
85842      break
85843    }
85844  }
85845
85846  if (x < y) return -1
85847  if (y < x) return 1
85848  return 0
85849}
85850
85851Buffer.isEncoding = function isEncoding (encoding) {
85852  switch (String(encoding).toLowerCase()) {
85853    case 'hex':
85854    case 'utf8':
85855    case 'utf-8':
85856    case 'ascii':
85857    case 'latin1':
85858    case 'binary':
85859    case 'base64':
85860    case 'ucs2':
85861    case 'ucs-2':
85862    case 'utf16le':
85863    case 'utf-16le':
85864      return true
85865    default:
85866      return false
85867  }
85868}
85869
85870Buffer.concat = function concat (list, length) {
85871  if (!isArray(list)) {
85872    throw new TypeError('"list" argument must be an Array of Buffers')
85873  }
85874
85875  if (list.length === 0) {
85876    return Buffer.alloc(0)
85877  }
85878
85879  var i
85880  if (length === undefined) {
85881    length = 0
85882    for (i = 0; i < list.length; ++i) {
85883      length += list[i].length
85884    }
85885  }
85886
85887  var buffer = Buffer.allocUnsafe(length)
85888  var pos = 0
85889  for (i = 0; i < list.length; ++i) {
85890    var buf = list[i]
85891    if (!Buffer.isBuffer(buf)) {
85892      throw new TypeError('"list" argument must be an Array of Buffers')
85893    }
85894    buf.copy(buffer, pos)
85895    pos += buf.length
85896  }
85897  return buffer
85898}
85899
85900function byteLength (string, encoding) {
85901  if (Buffer.isBuffer(string)) {
85902    return string.length
85903  }
85904  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
85905      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
85906    return string.byteLength
85907  }
85908  if (typeof string !== 'string') {
85909    string = '' + string
85910  }
85911
85912  var len = string.length
85913  if (len === 0) return 0
85914
85915  // Use a for loop to avoid recursion
85916  var loweredCase = false
85917  for (;;) {
85918    switch (encoding) {
85919      case 'ascii':
85920      case 'latin1':
85921      case 'binary':
85922        return len
85923      case 'utf8':
85924      case 'utf-8':
85925      case undefined:
85926        return utf8ToBytes(string).length
85927      case 'ucs2':
85928      case 'ucs-2':
85929      case 'utf16le':
85930      case 'utf-16le':
85931        return len * 2
85932      case 'hex':
85933        return len >>> 1
85934      case 'base64':
85935        return base64ToBytes(string).length
85936      default:
85937        if (loweredCase) return utf8ToBytes(string).length // assume utf8
85938        encoding = ('' + encoding).toLowerCase()
85939        loweredCase = true
85940    }
85941  }
85942}
85943Buffer.byteLength = byteLength
85944
85945function slowToString (encoding, start, end) {
85946  var loweredCase = false
85947
85948  // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
85949  // property of a typed array.
85950
85951  // This behaves neither like String nor Uint8Array in that we set start/end
85952  // to their upper/lower bounds if the value passed is out of range.
85953  // undefined is handled specially as per ECMA-262 6th Edition,
85954  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
85955  if (start === undefined || start < 0) {
85956    start = 0
85957  }
85958  // Return early if start > this.length. Done here to prevent potential uint32
85959  // coercion fail below.
85960  if (start > this.length) {
85961    return ''
85962  }
85963
85964  if (end === undefined || end > this.length) {
85965    end = this.length
85966  }
85967
85968  if (end <= 0) {
85969    return ''
85970  }
85971
85972  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
85973  end >>>= 0
85974  start >>>= 0
85975
85976  if (end <= start) {
85977    return ''
85978  }
85979
85980  if (!encoding) encoding = 'utf8'
85981
85982  while (true) {
85983    switch (encoding) {
85984      case 'hex':
85985        return hexSlice(this, start, end)
85986
85987      case 'utf8':
85988      case 'utf-8':
85989        return utf8Slice(this, start, end)
85990
85991      case 'ascii':
85992        return asciiSlice(this, start, end)
85993
85994      case 'latin1':
85995      case 'binary':
85996        return latin1Slice(this, start, end)
85997
85998      case 'base64':
85999        return base64Slice(this, start, end)
86000
86001      case 'ucs2':
86002      case 'ucs-2':
86003      case 'utf16le':
86004      case 'utf-16le':
86005        return utf16leSlice(this, start, end)
86006
86007      default:
86008        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
86009        encoding = (encoding + '').toLowerCase()
86010        loweredCase = true
86011    }
86012  }
86013}
86014
86015// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
86016// Buffer instances.
86017Buffer.prototype._isBuffer = true
86018
86019function swap (b, n, m) {
86020  var i = b[n]
86021  b[n] = b[m]
86022  b[m] = i
86023}
86024
86025Buffer.prototype.swap16 = function swap16 () {
86026  var len = this.length
86027  if (len % 2 !== 0) {
86028    throw new RangeError('Buffer size must be a multiple of 16-bits')
86029  }
86030  for (var i = 0; i < len; i += 2) {
86031    swap(this, i, i + 1)
86032  }
86033  return this
86034}
86035
86036Buffer.prototype.swap32 = function swap32 () {
86037  var len = this.length
86038  if (len % 4 !== 0) {
86039    throw new RangeError('Buffer size must be a multiple of 32-bits')
86040  }
86041  for (var i = 0; i < len; i += 4) {
86042    swap(this, i, i + 3)
86043    swap(this, i + 1, i + 2)
86044  }
86045  return this
86046}
86047
86048Buffer.prototype.swap64 = function swap64 () {
86049  var len = this.length
86050  if (len % 8 !== 0) {
86051    throw new RangeError('Buffer size must be a multiple of 64-bits')
86052  }
86053  for (var i = 0; i < len; i += 8) {
86054    swap(this, i, i + 7)
86055    swap(this, i + 1, i + 6)
86056    swap(this, i + 2, i + 5)
86057    swap(this, i + 3, i + 4)
86058  }
86059  return this
86060}
86061
86062Buffer.prototype.toString = function toString () {
86063  var length = this.length | 0
86064  if (length === 0) return ''
86065  if (arguments.length === 0) return utf8Slice(this, 0, length)
86066  return slowToString.apply(this, arguments)
86067}
86068
86069Buffer.prototype.equals = function equals (b) {
86070  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
86071  if (this === b) return true
86072  return Buffer.compare(this, b) === 0
86073}
86074
86075Buffer.prototype.inspect = function inspect () {
86076  var str = ''
86077  var max = exports.INSPECT_MAX_BYTES
86078  if (this.length > 0) {
86079    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
86080    if (this.length > max) str += ' ... '
86081  }
86082  return '<Buffer ' + str + '>'
86083}
86084
86085Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
86086  if (!Buffer.isBuffer(target)) {
86087    throw new TypeError('Argument must be a Buffer')
86088  }
86089
86090  if (start === undefined) {
86091    start = 0
86092  }
86093  if (end === undefined) {
86094    end = target ? target.length : 0
86095  }
86096  if (thisStart === undefined) {
86097    thisStart = 0
86098  }
86099  if (thisEnd === undefined) {
86100    thisEnd = this.length
86101  }
86102
86103  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
86104    throw new RangeError('out of range index')
86105  }
86106
86107  if (thisStart >= thisEnd && start >= end) {
86108    return 0
86109  }
86110  if (thisStart >= thisEnd) {
86111    return -1
86112  }
86113  if (start >= end) {
86114    return 1
86115  }
86116
86117  start >>>= 0
86118  end >>>= 0
86119  thisStart >>>= 0
86120  thisEnd >>>= 0
86121
86122  if (this === target) return 0
86123
86124  var x = thisEnd - thisStart
86125  var y = end - start
86126  var len = Math.min(x, y)
86127
86128  var thisCopy = this.slice(thisStart, thisEnd)
86129  var targetCopy = target.slice(start, end)
86130
86131  for (var i = 0; i < len; ++i) {
86132    if (thisCopy[i] !== targetCopy[i]) {
86133      x = thisCopy[i]
86134      y = targetCopy[i]
86135      break
86136    }
86137  }
86138
86139  if (x < y) return -1
86140  if (y < x) return 1
86141  return 0
86142}
86143
86144// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
86145// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
86146//
86147// Arguments:
86148// - buffer - a Buffer to search
86149// - val - a string, Buffer, or number
86150// - byteOffset - an index into `buffer`; will be clamped to an int32
86151// - encoding - an optional encoding, relevant is val is a string
86152// - dir - true for indexOf, false for lastIndexOf
86153function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
86154  // Empty buffer means no match
86155  if (buffer.length === 0) return -1
86156
86157  // Normalize byteOffset
86158  if (typeof byteOffset === 'string') {
86159    encoding = byteOffset
86160    byteOffset = 0
86161  } else if (byteOffset > 0x7fffffff) {
86162    byteOffset = 0x7fffffff
86163  } else if (byteOffset < -0x80000000) {
86164    byteOffset = -0x80000000
86165  }
86166  byteOffset = +byteOffset  // Coerce to Number.
86167  if (isNaN(byteOffset)) {
86168    // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
86169    byteOffset = dir ? 0 : (buffer.length - 1)
86170  }
86171
86172  // Normalize byteOffset: negative offsets start from the end of the buffer
86173  if (byteOffset < 0) byteOffset = buffer.length + byteOffset
86174  if (byteOffset >= buffer.length) {
86175    if (dir) return -1
86176    else byteOffset = buffer.length - 1
86177  } else if (byteOffset < 0) {
86178    if (dir) byteOffset = 0
86179    else return -1
86180  }
86181
86182  // Normalize val
86183  if (typeof val === 'string') {
86184    val = Buffer.from(val, encoding)
86185  }
86186
86187  // Finally, search either indexOf (if dir is true) or lastIndexOf
86188  if (Buffer.isBuffer(val)) {
86189    // Special case: looking for empty string/buffer always fails
86190    if (val.length === 0) {
86191      return -1
86192    }
86193    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
86194  } else if (typeof val === 'number') {
86195    val = val & 0xFF // Search for a byte value [0-255]
86196    if (Buffer.TYPED_ARRAY_SUPPORT &&
86197        typeof Uint8Array.prototype.indexOf === 'function') {
86198      if (dir) {
86199        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
86200      } else {
86201        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
86202      }
86203    }
86204    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
86205  }
86206
86207  throw new TypeError('val must be string, number or Buffer')
86208}
86209
86210function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
86211  var indexSize = 1
86212  var arrLength = arr.length
86213  var valLength = val.length
86214
86215  if (encoding !== undefined) {
86216    encoding = String(encoding).toLowerCase()
86217    if (encoding === 'ucs2' || encoding === 'ucs-2' ||
86218        encoding === 'utf16le' || encoding === 'utf-16le') {
86219      if (arr.length < 2 || val.length < 2) {
86220        return -1
86221      }
86222      indexSize = 2
86223      arrLength /= 2
86224      valLength /= 2
86225      byteOffset /= 2
86226    }
86227  }
86228
86229  function read (buf, i) {
86230    if (indexSize === 1) {
86231      return buf[i]
86232    } else {
86233      return buf.readUInt16BE(i * indexSize)
86234    }
86235  }
86236
86237  var i
86238  if (dir) {
86239    var foundIndex = -1
86240    for (i = byteOffset; i < arrLength; i++) {
86241      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
86242        if (foundIndex === -1) foundIndex = i
86243        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
86244      } else {
86245        if (foundIndex !== -1) i -= i - foundIndex
86246        foundIndex = -1
86247      }
86248    }
86249  } else {
86250    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
86251    for (i = byteOffset; i >= 0; i--) {
86252      var found = true
86253      for (var j = 0; j < valLength; j++) {
86254        if (read(arr, i + j) !== read(val, j)) {
86255          found = false
86256          break
86257        }
86258      }
86259      if (found) return i
86260    }
86261  }
86262
86263  return -1
86264}
86265
86266Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
86267  return this.indexOf(val, byteOffset, encoding) !== -1
86268}
86269
86270Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
86271  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
86272}
86273
86274Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
86275  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
86276}
86277
86278function hexWrite (buf, string, offset, length) {
86279  offset = Number(offset) || 0
86280  var remaining = buf.length - offset
86281  if (!length) {
86282    length = remaining
86283  } else {
86284    length = Number(length)
86285    if (length > remaining) {
86286      length = remaining
86287    }
86288  }
86289
86290  // must be an even number of digits
86291  var strLen = string.length
86292  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
86293
86294  if (length > strLen / 2) {
86295    length = strLen / 2
86296  }
86297  for (var i = 0; i < length; ++i) {
86298    var parsed = parseInt(string.substr(i * 2, 2), 16)
86299    if (isNaN(parsed)) return i
86300    buf[offset + i] = parsed
86301  }
86302  return i
86303}
86304
86305function utf8Write (buf, string, offset, length) {
86306  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
86307}
86308
86309function asciiWrite (buf, string, offset, length) {
86310  return blitBuffer(asciiToBytes(string), buf, offset, length)
86311}
86312
86313function latin1Write (buf, string, offset, length) {
86314  return asciiWrite(buf, string, offset, length)
86315}
86316
86317function base64Write (buf, string, offset, length) {
86318  return blitBuffer(base64ToBytes(string), buf, offset, length)
86319}
86320
86321function ucs2Write (buf, string, offset, length) {
86322  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
86323}
86324
86325Buffer.prototype.write = function write (string, offset, length, encoding) {
86326  // Buffer#write(string)
86327  if (offset === undefined) {
86328    encoding = 'utf8'
86329    length = this.length
86330    offset = 0
86331  // Buffer#write(string, encoding)
86332  } else if (length === undefined && typeof offset === 'string') {
86333    encoding = offset
86334    length = this.length
86335    offset = 0
86336  // Buffer#write(string, offset[, length][, encoding])
86337  } else if (isFinite(offset)) {
86338    offset = offset | 0
86339    if (isFinite(length)) {
86340      length = length | 0
86341      if (encoding === undefined) encoding = 'utf8'
86342    } else {
86343      encoding = length
86344      length = undefined
86345    }
86346  // legacy write(string, encoding, offset, length) - remove in v0.13
86347  } else {
86348    throw new Error(
86349      'Buffer.write(string, encoding, offset[, length]) is no longer supported'
86350    )
86351  }
86352
86353  var remaining = this.length - offset
86354  if (length === undefined || length > remaining) length = remaining
86355
86356  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
86357    throw new RangeError('Attempt to write outside buffer bounds')
86358  }
86359
86360  if (!encoding) encoding = 'utf8'
86361
86362  var loweredCase = false
86363  for (;;) {
86364    switch (encoding) {
86365      case 'hex':
86366        return hexWrite(this, string, offset, length)
86367
86368      case 'utf8':
86369      case 'utf-8':
86370        return utf8Write(this, string, offset, length)
86371
86372      case 'ascii':
86373        return asciiWrite(this, string, offset, length)
86374
86375      case 'latin1':
86376      case 'binary':
86377        return latin1Write(this, string, offset, length)
86378
86379      case 'base64':
86380        // Warning: maxLength not taken into account in base64Write
86381        return base64Write(this, string, offset, length)
86382
86383      case 'ucs2':
86384      case 'ucs-2':
86385      case 'utf16le':
86386      case 'utf-16le':
86387        return ucs2Write(this, string, offset, length)
86388
86389      default:
86390        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
86391        encoding = ('' + encoding).toLowerCase()
86392        loweredCase = true
86393    }
86394  }
86395}
86396
86397Buffer.prototype.toJSON = function toJSON () {
86398  return {
86399    type: 'Buffer',
86400    data: Array.prototype.slice.call(this._arr || this, 0)
86401  }
86402}
86403
86404function base64Slice (buf, start, end) {
86405  if (start === 0 && end === buf.length) {
86406    return base64.fromByteArray(buf)
86407  } else {
86408    return base64.fromByteArray(buf.slice(start, end))
86409  }
86410}
86411
86412function utf8Slice (buf, start, end) {
86413  end = Math.min(buf.length, end)
86414  var res = []
86415
86416  var i = start
86417  while (i < end) {
86418    var firstByte = buf[i]
86419    var codePoint = null
86420    var bytesPerSequence = (firstByte > 0xEF) ? 4
86421      : (firstByte > 0xDF) ? 3
86422      : (firstByte > 0xBF) ? 2
86423      : 1
86424
86425    if (i + bytesPerSequence <= end) {
86426      var secondByte, thirdByte, fourthByte, tempCodePoint
86427
86428      switch (bytesPerSequence) {
86429        case 1:
86430          if (firstByte < 0x80) {
86431            codePoint = firstByte
86432          }
86433          break
86434        case 2:
86435          secondByte = buf[i + 1]
86436          if ((secondByte & 0xC0) === 0x80) {
86437            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
86438            if (tempCodePoint > 0x7F) {
86439              codePoint = tempCodePoint
86440            }
86441          }
86442          break
86443        case 3:
86444          secondByte = buf[i + 1]
86445          thirdByte = buf[i + 2]
86446          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
86447            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
86448            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
86449              codePoint = tempCodePoint
86450            }
86451          }
86452          break
86453        case 4:
86454          secondByte = buf[i + 1]
86455          thirdByte = buf[i + 2]
86456          fourthByte = buf[i + 3]
86457          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
86458            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
86459            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
86460              codePoint = tempCodePoint
86461            }
86462          }
86463      }
86464    }
86465
86466    if (codePoint === null) {
86467      // we did not generate a valid codePoint so insert a
86468      // replacement char (U+FFFD) and advance only 1 byte
86469      codePoint = 0xFFFD
86470      bytesPerSequence = 1
86471    } else if (codePoint > 0xFFFF) {
86472      // encode to utf16 (surrogate pair dance)
86473      codePoint -= 0x10000
86474      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
86475      codePoint = 0xDC00 | codePoint & 0x3FF
86476    }
86477
86478    res.push(codePoint)
86479    i += bytesPerSequence
86480  }
86481
86482  return decodeCodePointsArray(res)
86483}
86484
86485// Based on http://stackoverflow.com/a/22747272/680742, the browser with
86486// the lowest limit is Chrome, with 0x10000 args.
86487// We go 1 magnitude less, for safety
86488var MAX_ARGUMENTS_LENGTH = 0x1000
86489
86490function decodeCodePointsArray (codePoints) {
86491  var len = codePoints.length
86492  if (len <= MAX_ARGUMENTS_LENGTH) {
86493    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
86494  }
86495
86496  // Decode in chunks to avoid "call stack size exceeded".
86497  var res = ''
86498  var i = 0
86499  while (i < len) {
86500    res += String.fromCharCode.apply(
86501      String,
86502      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
86503    )
86504  }
86505  return res
86506}
86507
86508function asciiSlice (buf, start, end) {
86509  var ret = ''
86510  end = Math.min(buf.length, end)
86511
86512  for (var i = start; i < end; ++i) {
86513    ret += String.fromCharCode(buf[i] & 0x7F)
86514  }
86515  return ret
86516}
86517
86518function latin1Slice (buf, start, end) {
86519  var ret = ''
86520  end = Math.min(buf.length, end)
86521
86522  for (var i = start; i < end; ++i) {
86523    ret += String.fromCharCode(buf[i])
86524  }
86525  return ret
86526}
86527
86528function hexSlice (buf, start, end) {
86529  var len = buf.length
86530
86531  if (!start || start < 0) start = 0
86532  if (!end || end < 0 || end > len) end = len
86533
86534  var out = ''
86535  for (var i = start; i < end; ++i) {
86536    out += toHex(buf[i])
86537  }
86538  return out
86539}
86540
86541function utf16leSlice (buf, start, end) {
86542  var bytes = buf.slice(start, end)
86543  var res = ''
86544  for (var i = 0; i < bytes.length; i += 2) {
86545    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
86546  }
86547  return res
86548}
86549
86550Buffer.prototype.slice = function slice (start, end) {
86551  var len = this.length
86552  start = ~~start
86553  end = end === undefined ? len : ~~end
86554
86555  if (start < 0) {
86556    start += len
86557    if (start < 0) start = 0
86558  } else if (start > len) {
86559    start = len
86560  }
86561
86562  if (end < 0) {
86563    end += len
86564    if (end < 0) end = 0
86565  } else if (end > len) {
86566    end = len
86567  }
86568
86569  if (end < start) end = start
86570
86571  var newBuf
86572  if (Buffer.TYPED_ARRAY_SUPPORT) {
86573    newBuf = this.subarray(start, end)
86574    newBuf.__proto__ = Buffer.prototype
86575  } else {
86576    var sliceLen = end - start
86577    newBuf = new Buffer(sliceLen, undefined)
86578    for (var i = 0; i < sliceLen; ++i) {
86579      newBuf[i] = this[i + start]
86580    }
86581  }
86582
86583  return newBuf
86584}
86585
86586/*
86587 * Need to make sure that buffer isn't trying to write out of bounds.
86588 */
86589function checkOffset (offset, ext, length) {
86590  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
86591  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
86592}
86593
86594Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
86595  offset = offset | 0
86596  byteLength = byteLength | 0
86597  if (!noAssert) checkOffset(offset, byteLength, this.length)
86598
86599  var val = this[offset]
86600  var mul = 1
86601  var i = 0
86602  while (++i < byteLength && (mul *= 0x100)) {
86603    val += this[offset + i] * mul
86604  }
86605
86606  return val
86607}
86608
86609Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
86610  offset = offset | 0
86611  byteLength = byteLength | 0
86612  if (!noAssert) {
86613    checkOffset(offset, byteLength, this.length)
86614  }
86615
86616  var val = this[offset + --byteLength]
86617  var mul = 1
86618  while (byteLength > 0 && (mul *= 0x100)) {
86619    val += this[offset + --byteLength] * mul
86620  }
86621
86622  return val
86623}
86624
86625Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
86626  if (!noAssert) checkOffset(offset, 1, this.length)
86627  return this[offset]
86628}
86629
86630Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
86631  if (!noAssert) checkOffset(offset, 2, this.length)
86632  return this[offset] | (this[offset + 1] << 8)
86633}
86634
86635Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
86636  if (!noAssert) checkOffset(offset, 2, this.length)
86637  return (this[offset] << 8) | this[offset + 1]
86638}
86639
86640Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
86641  if (!noAssert) checkOffset(offset, 4, this.length)
86642
86643  return ((this[offset]) |
86644      (this[offset + 1] << 8) |
86645      (this[offset + 2] << 16)) +
86646      (this[offset + 3] * 0x1000000)
86647}
86648
86649Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
86650  if (!noAssert) checkOffset(offset, 4, this.length)
86651
86652  return (this[offset] * 0x1000000) +
86653    ((this[offset + 1] << 16) |
86654    (this[offset + 2] << 8) |
86655    this[offset + 3])
86656}
86657
86658Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
86659  offset = offset | 0
86660  byteLength = byteLength | 0
86661  if (!noAssert) checkOffset(offset, byteLength, this.length)
86662
86663  var val = this[offset]
86664  var mul = 1
86665  var i = 0
86666  while (++i < byteLength && (mul *= 0x100)) {
86667    val += this[offset + i] * mul
86668  }
86669  mul *= 0x80
86670
86671  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
86672
86673  return val
86674}
86675
86676Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
86677  offset = offset | 0
86678  byteLength = byteLength | 0
86679  if (!noAssert) checkOffset(offset, byteLength, this.length)
86680
86681  var i = byteLength
86682  var mul = 1
86683  var val = this[offset + --i]
86684  while (i > 0 && (mul *= 0x100)) {
86685    val += this[offset + --i] * mul
86686  }
86687  mul *= 0x80
86688
86689  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
86690
86691  return val
86692}
86693
86694Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
86695  if (!noAssert) checkOffset(offset, 1, this.length)
86696  if (!(this[offset] & 0x80)) return (this[offset])
86697  return ((0xff - this[offset] + 1) * -1)
86698}
86699
86700Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
86701  if (!noAssert) checkOffset(offset, 2, this.length)
86702  var val = this[offset] | (this[offset + 1] << 8)
86703  return (val & 0x8000) ? val | 0xFFFF0000 : val
86704}
86705
86706Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
86707  if (!noAssert) checkOffset(offset, 2, this.length)
86708  var val = this[offset + 1] | (this[offset] << 8)
86709  return (val & 0x8000) ? val | 0xFFFF0000 : val
86710}
86711
86712Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
86713  if (!noAssert) checkOffset(offset, 4, this.length)
86714
86715  return (this[offset]) |
86716    (this[offset + 1] << 8) |
86717    (this[offset + 2] << 16) |
86718    (this[offset + 3] << 24)
86719}
86720
86721Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
86722  if (!noAssert) checkOffset(offset, 4, this.length)
86723
86724  return (this[offset] << 24) |
86725    (this[offset + 1] << 16) |
86726    (this[offset + 2] << 8) |
86727    (this[offset + 3])
86728}
86729
86730Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
86731  if (!noAssert) checkOffset(offset, 4, this.length)
86732  return ieee754.read(this, offset, true, 23, 4)
86733}
86734
86735Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
86736  if (!noAssert) checkOffset(offset, 4, this.length)
86737  return ieee754.read(this, offset, false, 23, 4)
86738}
86739
86740Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
86741  if (!noAssert) checkOffset(offset, 8, this.length)
86742  return ieee754.read(this, offset, true, 52, 8)
86743}
86744
86745Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
86746  if (!noAssert) checkOffset(offset, 8, this.length)
86747  return ieee754.read(this, offset, false, 52, 8)
86748}
86749
86750function checkInt (buf, value, offset, ext, max, min) {
86751  if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
86752  if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
86753  if (offset + ext > buf.length) throw new RangeError('Index out of range')
86754}
86755
86756Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
86757  value = +value
86758  offset = offset | 0
86759  byteLength = byteLength | 0
86760  if (!noAssert) {
86761    var maxBytes = Math.pow(2, 8 * byteLength) - 1
86762    checkInt(this, value, offset, byteLength, maxBytes, 0)
86763  }
86764
86765  var mul = 1
86766  var i = 0
86767  this[offset] = value & 0xFF
86768  while (++i < byteLength && (mul *= 0x100)) {
86769    this[offset + i] = (value / mul) & 0xFF
86770  }
86771
86772  return offset + byteLength
86773}
86774
86775Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
86776  value = +value
86777  offset = offset | 0
86778  byteLength = byteLength | 0
86779  if (!noAssert) {
86780    var maxBytes = Math.pow(2, 8 * byteLength) - 1
86781    checkInt(this, value, offset, byteLength, maxBytes, 0)
86782  }
86783
86784  var i = byteLength - 1
86785  var mul = 1
86786  this[offset + i] = value & 0xFF
86787  while (--i >= 0 && (mul *= 0x100)) {
86788    this[offset + i] = (value / mul) & 0xFF
86789  }
86790
86791  return offset + byteLength
86792}
86793
86794Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
86795  value = +value
86796  offset = offset | 0
86797  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
86798  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
86799  this[offset] = (value & 0xff)
86800  return offset + 1
86801}
86802
86803function objectWriteUInt16 (buf, value, offset, littleEndian) {
86804  if (value < 0) value = 0xffff + value + 1
86805  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
86806    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
86807      (littleEndian ? i : 1 - i) * 8
86808  }
86809}
86810
86811Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
86812  value = +value
86813  offset = offset | 0
86814  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
86815  if (Buffer.TYPED_ARRAY_SUPPORT) {
86816    this[offset] = (value & 0xff)
86817    this[offset + 1] = (value >>> 8)
86818  } else {
86819    objectWriteUInt16(this, value, offset, true)
86820  }
86821  return offset + 2
86822}
86823
86824Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
86825  value = +value
86826  offset = offset | 0
86827  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
86828  if (Buffer.TYPED_ARRAY_SUPPORT) {
86829    this[offset] = (value >>> 8)
86830    this[offset + 1] = (value & 0xff)
86831  } else {
86832    objectWriteUInt16(this, value, offset, false)
86833  }
86834  return offset + 2
86835}
86836
86837function objectWriteUInt32 (buf, value, offset, littleEndian) {
86838  if (value < 0) value = 0xffffffff + value + 1
86839  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
86840    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
86841  }
86842}
86843
86844Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
86845  value = +value
86846  offset = offset | 0
86847  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
86848  if (Buffer.TYPED_ARRAY_SUPPORT) {
86849    this[offset + 3] = (value >>> 24)
86850    this[offset + 2] = (value >>> 16)
86851    this[offset + 1] = (value >>> 8)
86852    this[offset] = (value & 0xff)
86853  } else {
86854    objectWriteUInt32(this, value, offset, true)
86855  }
86856  return offset + 4
86857}
86858
86859Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
86860  value = +value
86861  offset = offset | 0
86862  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
86863  if (Buffer.TYPED_ARRAY_SUPPORT) {
86864    this[offset] = (value >>> 24)
86865    this[offset + 1] = (value >>> 16)
86866    this[offset + 2] = (value >>> 8)
86867    this[offset + 3] = (value & 0xff)
86868  } else {
86869    objectWriteUInt32(this, value, offset, false)
86870  }
86871  return offset + 4
86872}
86873
86874Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
86875  value = +value
86876  offset = offset | 0
86877  if (!noAssert) {
86878    var limit = Math.pow(2, 8 * byteLength - 1)
86879
86880    checkInt(this, value, offset, byteLength, limit - 1, -limit)
86881  }
86882
86883  var i = 0
86884  var mul = 1
86885  var sub = 0
86886  this[offset] = value & 0xFF
86887  while (++i < byteLength && (mul *= 0x100)) {
86888    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
86889      sub = 1
86890    }
86891    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
86892  }
86893
86894  return offset + byteLength
86895}
86896
86897Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
86898  value = +value
86899  offset = offset | 0
86900  if (!noAssert) {
86901    var limit = Math.pow(2, 8 * byteLength - 1)
86902
86903    checkInt(this, value, offset, byteLength, limit - 1, -limit)
86904  }
86905
86906  var i = byteLength - 1
86907  var mul = 1
86908  var sub = 0
86909  this[offset + i] = value & 0xFF
86910  while (--i >= 0 && (mul *= 0x100)) {
86911    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
86912      sub = 1
86913    }
86914    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
86915  }
86916
86917  return offset + byteLength
86918}
86919
86920Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
86921  value = +value
86922  offset = offset | 0
86923  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
86924  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
86925  if (value < 0) value = 0xff + value + 1
86926  this[offset] = (value & 0xff)
86927  return offset + 1
86928}
86929
86930Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
86931  value = +value
86932  offset = offset | 0
86933  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
86934  if (Buffer.TYPED_ARRAY_SUPPORT) {
86935    this[offset] = (value & 0xff)
86936    this[offset + 1] = (value >>> 8)
86937  } else {
86938    objectWriteUInt16(this, value, offset, true)
86939  }
86940  return offset + 2
86941}
86942
86943Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
86944  value = +value
86945  offset = offset | 0
86946  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
86947  if (Buffer.TYPED_ARRAY_SUPPORT) {
86948    this[offset] = (value >>> 8)
86949    this[offset + 1] = (value & 0xff)
86950  } else {
86951    objectWriteUInt16(this, value, offset, false)
86952  }
86953  return offset + 2
86954}
86955
86956Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
86957  value = +value
86958  offset = offset | 0
86959  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
86960  if (Buffer.TYPED_ARRAY_SUPPORT) {
86961    this[offset] = (value & 0xff)
86962    this[offset + 1] = (value >>> 8)
86963    this[offset + 2] = (value >>> 16)
86964    this[offset + 3] = (value >>> 24)
86965  } else {
86966    objectWriteUInt32(this, value, offset, true)
86967  }
86968  return offset + 4
86969}
86970
86971Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
86972  value = +value
86973  offset = offset | 0
86974  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
86975  if (value < 0) value = 0xffffffff + value + 1
86976  if (Buffer.TYPED_ARRAY_SUPPORT) {
86977    this[offset] = (value >>> 24)
86978    this[offset + 1] = (value >>> 16)
86979    this[offset + 2] = (value >>> 8)
86980    this[offset + 3] = (value & 0xff)
86981  } else {
86982    objectWriteUInt32(this, value, offset, false)
86983  }
86984  return offset + 4
86985}
86986
86987function checkIEEE754 (buf, value, offset, ext, max, min) {
86988  if (offset + ext > buf.length) throw new RangeError('Index out of range')
86989  if (offset < 0) throw new RangeError('Index out of range')
86990}
86991
86992function writeFloat (buf, value, offset, littleEndian, noAssert) {
86993  if (!noAssert) {
86994    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
86995  }
86996  ieee754.write(buf, value, offset, littleEndian, 23, 4)
86997  return offset + 4
86998}
86999
87000Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
87001  return writeFloat(this, value, offset, true, noAssert)
87002}
87003
87004Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
87005  return writeFloat(this, value, offset, false, noAssert)
87006}
87007
87008function writeDouble (buf, value, offset, littleEndian, noAssert) {
87009  if (!noAssert) {
87010    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
87011  }
87012  ieee754.write(buf, value, offset, littleEndian, 52, 8)
87013  return offset + 8
87014}
87015
87016Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
87017  return writeDouble(this, value, offset, true, noAssert)
87018}
87019
87020Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
87021  return writeDouble(this, value, offset, false, noAssert)
87022}
87023
87024// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
87025Buffer.prototype.copy = function copy (target, targetStart, start, end) {
87026  if (!start) start = 0
87027  if (!end && end !== 0) end = this.length
87028  if (targetStart >= target.length) targetStart = target.length
87029  if (!targetStart) targetStart = 0
87030  if (end > 0 && end < start) end = start
87031
87032  // Copy 0 bytes; we're done
87033  if (end === start) return 0
87034  if (target.length === 0 || this.length === 0) return 0
87035
87036  // Fatal error conditions
87037  if (targetStart < 0) {
87038    throw new RangeError('targetStart out of bounds')
87039  }
87040  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
87041  if (end < 0) throw new RangeError('sourceEnd out of bounds')
87042
87043  // Are we oob?
87044  if (end > this.length) end = this.length
87045  if (target.length - targetStart < end - start) {
87046    end = target.length - targetStart + start
87047  }
87048
87049  var len = end - start
87050  var i
87051
87052  if (this === target && start < targetStart && targetStart < end) {
87053    // descending copy from end
87054    for (i = len - 1; i >= 0; --i) {
87055      target[i + targetStart] = this[i + start]
87056    }
87057  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
87058    // ascending copy from start
87059    for (i = 0; i < len; ++i) {
87060      target[i + targetStart] = this[i + start]
87061    }
87062  } else {
87063    Uint8Array.prototype.set.call(
87064      target,
87065      this.subarray(start, start + len),
87066      targetStart
87067    )
87068  }
87069
87070  return len
87071}
87072
87073// Usage:
87074//    buffer.fill(number[, offset[, end]])
87075//    buffer.fill(buffer[, offset[, end]])
87076//    buffer.fill(string[, offset[, end]][, encoding])
87077Buffer.prototype.fill = function fill (val, start, end, encoding) {
87078  // Handle string cases:
87079  if (typeof val === 'string') {
87080    if (typeof start === 'string') {
87081      encoding = start
87082      start = 0
87083      end = this.length
87084    } else if (typeof end === 'string') {
87085      encoding = end
87086      end = this.length
87087    }
87088    if (val.length === 1) {
87089      var code = val.charCodeAt(0)
87090      if (code < 256) {
87091        val = code
87092      }
87093    }
87094    if (encoding !== undefined && typeof encoding !== 'string') {
87095      throw new TypeError('encoding must be a string')
87096    }
87097    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
87098      throw new TypeError('Unknown encoding: ' + encoding)
87099    }
87100  } else if (typeof val === 'number') {
87101    val = val & 255
87102  }
87103
87104  // Invalid ranges are not set to a default, so can range check early.
87105  if (start < 0 || this.length < start || this.length < end) {
87106    throw new RangeError('Out of range index')
87107  }
87108
87109  if (end <= start) {
87110    return this
87111  }
87112
87113  start = start >>> 0
87114  end = end === undefined ? this.length : end >>> 0
87115
87116  if (!val) val = 0
87117
87118  var i
87119  if (typeof val === 'number') {
87120    for (i = start; i < end; ++i) {
87121      this[i] = val
87122    }
87123  } else {
87124    var bytes = Buffer.isBuffer(val)
87125      ? val
87126      : utf8ToBytes(new Buffer(val, encoding).toString())
87127    var len = bytes.length
87128    for (i = 0; i < end - start; ++i) {
87129      this[i + start] = bytes[i % len]
87130    }
87131  }
87132
87133  return this
87134}
87135
87136// HELPER FUNCTIONS
87137// ================
87138
87139var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
87140
87141function base64clean (str) {
87142  // Node strips out invalid characters like \n and \t from the string, base64-js does not
87143  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
87144  // Node converts strings with length < 2 to ''
87145  if (str.length < 2) return ''
87146  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
87147  while (str.length % 4 !== 0) {
87148    str = str + '='
87149  }
87150  return str
87151}
87152
87153function stringtrim (str) {
87154  if (str.trim) return str.trim()
87155  return str.replace(/^\s+|\s+$/g, '')
87156}
87157
87158function toHex (n) {
87159  if (n < 16) return '0' + n.toString(16)
87160  return n.toString(16)
87161}
87162
87163function utf8ToBytes (string, units) {
87164  units = units || Infinity
87165  var codePoint
87166  var length = string.length
87167  var leadSurrogate = null
87168  var bytes = []
87169
87170  for (var i = 0; i < length; ++i) {
87171    codePoint = string.charCodeAt(i)
87172
87173    // is surrogate component
87174    if (codePoint > 0xD7FF && codePoint < 0xE000) {
87175      // last char was a lead
87176      if (!leadSurrogate) {
87177        // no lead yet
87178        if (codePoint > 0xDBFF) {
87179          // unexpected trail
87180          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
87181          continue
87182        } else if (i + 1 === length) {
87183          // unpaired lead
87184          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
87185          continue
87186        }
87187
87188        // valid lead
87189        leadSurrogate = codePoint
87190
87191        continue
87192      }
87193
87194      // 2 leads in a row
87195      if (codePoint < 0xDC00) {
87196        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
87197        leadSurrogate = codePoint
87198        continue
87199      }
87200
87201      // valid surrogate pair
87202      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
87203    } else if (leadSurrogate) {
87204      // valid bmp char, but last char was a lead
87205      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
87206    }
87207
87208    leadSurrogate = null
87209
87210    // encode utf8
87211    if (codePoint < 0x80) {
87212      if ((units -= 1) < 0) break
87213      bytes.push(codePoint)
87214    } else if (codePoint < 0x800) {
87215      if ((units -= 2) < 0) break
87216      bytes.push(
87217        codePoint >> 0x6 | 0xC0,
87218        codePoint & 0x3F | 0x80
87219      )
87220    } else if (codePoint < 0x10000) {
87221      if ((units -= 3) < 0) break
87222      bytes.push(
87223        codePoint >> 0xC | 0xE0,
87224        codePoint >> 0x6 & 0x3F | 0x80,
87225        codePoint & 0x3F | 0x80
87226      )
87227    } else if (codePoint < 0x110000) {
87228      if ((units -= 4) < 0) break
87229      bytes.push(
87230        codePoint >> 0x12 | 0xF0,
87231        codePoint >> 0xC & 0x3F | 0x80,
87232        codePoint >> 0x6 & 0x3F | 0x80,
87233        codePoint & 0x3F | 0x80
87234      )
87235    } else {
87236      throw new Error('Invalid code point')
87237    }
87238  }
87239
87240  return bytes
87241}
87242
87243function asciiToBytes (str) {
87244  var byteArray = []
87245  for (var i = 0; i < str.length; ++i) {
87246    // Node's code seems to be doing this and not & 0x7F..
87247    byteArray.push(str.charCodeAt(i) & 0xFF)
87248  }
87249  return byteArray
87250}
87251
87252function utf16leToBytes (str, units) {
87253  var c, hi, lo
87254  var byteArray = []
87255  for (var i = 0; i < str.length; ++i) {
87256    if ((units -= 2) < 0) break
87257
87258    c = str.charCodeAt(i)
87259    hi = c >> 8
87260    lo = c % 256
87261    byteArray.push(lo)
87262    byteArray.push(hi)
87263  }
87264
87265  return byteArray
87266}
87267
87268function base64ToBytes (str) {
87269  return base64.toByteArray(base64clean(str))
87270}
87271
87272function blitBuffer (src, dst, offset, length) {
87273  for (var i = 0; i < length; ++i) {
87274    if ((i + offset >= dst.length) || (i >= src.length)) break
87275    dst[i + offset] = src[i]
87276  }
87277  return i
87278}
87279
87280function isnan (val) {
87281  return val !== val // eslint-disable-line no-self-compare
87282}
87283
87284/* WEBPACK VAR INJECTION */}.call(
vendor: 9,082 bytes, lines 87284-87632
87284exports, __webpack_require__(257)))
87285
87286/***/ }),
87287/* 257 */
87288/***/ (function(module, exports) {
87289
87290var g;
87291
87292// This works in non-strict mode
87293g = (function() {
87294	return this;
87295})();
87296
87297try {
87298	// This works if eval is allowed (see CSP)
87299	g = g || Function("return this")() || (1,eval)("this");
87300} catch(e) {
87301	// This works if the window reference is available
87302	if(typeof window === "object")
87303		g = window;
87304}
87305
87306// g can still be undefined, but nothing to do about it...
87307// We return undefined, instead of nothing here, so it's
87308// easier to handle this case. if(!global) { ...}
87309
87310module.exports = g;
87311
87312
87313/***/ }),
87314/* 258 */
87315/***/ (function(module, exports, __webpack_require__) {
87316
87317"use strict";
87318
87319
87320exports.byteLength = byteLength
87321exports.toByteArray = toByteArray
87322exports.fromByteArray = fromByteArray
87323
87324var lookup = []
87325var revLookup = []
87326var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
87327
87328var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
87329for (var i = 0, len = code.length; i < len; ++i) {
87330  lookup[i] = code[i]
87331  revLookup[code.charCodeAt(i)] = i
87332}
87333
87334// Support decoding URL-safe base64 strings, as Node.js does.
87335// See: https://en.wikipedia.org/wiki/Base64#URL_applications
87336revLookup['-'.charCodeAt(0)] = 62
87337revLookup['_'.charCodeAt(0)] = 63
87338
87339function getLens (b64) {
87340  var len = b64.length
87341
87342  if (len % 4 > 0) {
87343    throw new Error('Invalid string. Length must be a multiple of 4')
87344  }
87345
87346  // Trim off extra bytes after placeholder bytes are found
87347  // See: https://github.com/beatgammit/base64-js/issues/42
87348  var validLen = b64.indexOf('=')
87349  if (validLen === -1) validLen = len
87350
87351  var placeHoldersLen = validLen === len
87352    ? 0
87353    : 4 - (validLen % 4)
87354
87355  return [validLen, placeHoldersLen]
87356}
87357
87358// base64 is 4/3 + up to two characters of the original data
87359function byteLength (b64) {
87360  var lens = getLens(b64)
87361  var validLen = lens[0]
87362  var placeHoldersLen = lens[1]
87363  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
87364}
87365
87366function _byteLength (b64, validLen, placeHoldersLen) {
87367  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
87368}
87369
87370function toByteArray (b64) {
87371  var tmp
87372  var lens = getLens(b64)
87373  var validLen = lens[0]
87374  var placeHoldersLen = lens[1]
87375
87376  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
87377
87378  var curByte = 0
87379
87380  // if there are placeholders, only get up to the last complete 4 chars
87381  var len = placeHoldersLen > 0
87382    ? validLen - 4
87383    : validLen
87384
87385  var i
87386  for (i = 0; i < len; i += 4) {
87387    tmp =
87388      (revLookup[b64.charCodeAt(i)] << 18) |
87389      (revLookup[b64.charCodeAt(i + 1)] << 12) |
87390      (revLookup[b64.charCodeAt(i + 2)] << 6) |
87391      revLookup[b64.charCodeAt(i + 3)]
87392    arr[curByte++] = (tmp >> 16) & 0xFF
87393    arr[curByte++] = (tmp >> 8) & 0xFF
87394    arr[curByte++] = tmp & 0xFF
87395  }
87396
87397  if (placeHoldersLen === 2) {
87398    tmp =
87399      (revLookup[b64.charCodeAt(i)] << 2) |
87400      (revLookup[b64.charCodeAt(i + 1)] >> 4)
87401    arr[curByte++] = tmp & 0xFF
87402  }
87403
87404  if (placeHoldersLen === 1) {
87405    tmp =
87406      (revLookup[b64.charCodeAt(i)] << 10) |
87407      (revLookup[b64.charCodeAt(i + 1)] << 4) |
87408      (revLookup[b64.charCodeAt(i + 2)] >> 2)
87409    arr[curByte++] = (tmp >> 8) & 0xFF
87410    arr[curByte++] = tmp & 0xFF
87411  }
87412
87413  return arr
87414}
87415
87416function tripletToBase64 (num) {
87417  return lookup[num >> 18 & 0x3F] +
87418    lookup[num >> 12 & 0x3F] +
87419    lookup[num >> 6 & 0x3F] +
87420    lookup[num & 0x3F]
87421}
87422
87423function encodeChunk (uint8, start, end) {
87424  var tmp
87425  var output = []
87426  for (var i = start; i < end; i += 3) {
87427    tmp =
87428      ((uint8[i] << 16) & 0xFF0000) +
87429      ((uint8[i + 1] << 8) & 0xFF00) +
87430      (uint8[i + 2] & 0xFF)
87431    output.push(tripletToBase64(tmp))
87432  }
87433  return output.join('')
87434}
87435
87436function fromByteArray (uint8) {
87437  var tmp
87438  var len = uint8.length
87439  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
87440  var parts = []
87441  var maxChunkLength = 16383 // must be multiple of 3
87442
87443  // go through the array every three bytes, we'll deal with trailing stuff later
87444  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
87445    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
87446  }
87447
87448  // pad the end with zeros, but make sure to not forget the extra bytes
87449  if (extraBytes === 1) {
87450    tmp = uint8[len - 1]
87451    parts.push(
87452      lookup[tmp >> 2] +
87453      lookup[(tmp << 4) & 0x3F] +
87454      '=='
87455    )
87456  } else if (extraBytes === 2) {
87457    tmp = (uint8[len - 2] << 8) + uint8[len - 1]
87458    parts.push(
87459      lookup[tmp >> 10] +
87460      lookup[(tmp >> 4) & 0x3F] +
87461      lookup[(tmp << 2) & 0x3F] +
87462      '='
87463    )
87464  }
87465
87466  return parts.join('')
87467}
87468
87469
87470/***/ }),
87471/* 259 */
87472/***/ (function(module, exports) {
87473
87474/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
87475exports.read = function (buffer, offset, isLE, mLen, nBytes) {
87476  var e, m
87477  var eLen = (nBytes * 8) - mLen - 1
87478  var eMax = (1 << eLen) - 1
87479  var eBias = eMax >> 1
87480  var nBits = -7
87481  var i = isLE ? (nBytes - 1) : 0
87482  var d = isLE ? -1 : 1
87483  var s = buffer[offset + i]
87484
87485  i += d
87486
87487  e = s & ((1 << (-nBits)) - 1)
87488  s >>= (-nBits)
87489  nBits += eLen
87490  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
87491
87492  m = e & ((1 << (-nBits)) - 1)
87493  e >>= (-nBits)
87494  nBits += mLen
87495  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
87496
87497  if (e === 0) {
87498    e = 1 - eBias
87499  } else if (e === eMax) {
87500    return m ? NaN : ((s ? -1 : 1) * Infinity)
87501  } else {
87502    m = m + Math.pow(2, mLen)
87503    e = e - eBias
87504  }
87505  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
87506}
87507
87508exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
87509  var e, m, c
87510  var eLen = (nBytes * 8) - mLen - 1
87511  var eMax = (1 << eLen) - 1
87512  var eBias = eMax >> 1
87513  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
87514  var i = isLE ? 0 : (nBytes - 1)
87515  var d = isLE ? 1 : -1
87516  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
87517
87518  value = Math.abs(value)
87519
87520  if (isNaN(value) || value === Infinity) {
87521    m = isNaN(value) ? 1 : 0
87522    e = eMax
87523  } else {
87524    e = Math.floor(Math.log(value) / Math.LN2)
87525    if (value * (c = Math.pow(2, -e)) < 1) {
87526      e--
87527      c *= 2
87528    }
87529    if (e + eBias >= 1) {
87530      value += rt / c
87531    } else {
87532      value += rt * Math.pow(2, 1 - eBias)
87533    }
87534    if (value * c >= 2) {
87535      e++
87536      c /= 2
87537    }
87538
87539    if (e + eBias >= eMax) {
87540      m = 0
87541      e = eMax
87542    } else if (e + eBias >= 1) {
87543      m = ((value * c) - 1) * Math.pow(2, mLen)
87544      e = e + eBias
87545    } else {
87546      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
87547      e = 0
87548    }
87549  }
87550
87551  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
87552
87553  e = (e << mLen) | m
87554  eLen += mLen
87555  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
87556
87557  buffer[offset + i - d] |= s * 128
87558}
87559
87560
87561/***/ }),
87562/* 260 */
87563/***/ (function(module, exports) {
87564
87565var toString = {}.toString;
87566
87567module.exports = Array.isArray || function (arr) {
87568  return toString.call(arr) == '[object Array]';
87569};
87570
87571
87572/***/ }),
87573/* 261 */
87574/***/ (function(module, exports) {
87575
87576/* (ignored) */
87577
87578/***/ }),
87579/* 262 */
87580/***/ (function(module, exports) {
87581
87582/* (ignored) */
87583
87584/***/ }),
87585/* 263 */
87586/***/ (function(module, exports) {
87587
87588/* (ignored) */
87589
87590/***/ }),
87591/* 264 */
87592/***/ (function(module, exports, __webpack_require__) {
87593
87594/**
87595* Panzoom for panning and zooming elements using CSS transforms
87596* Copyright Timmy Willison and other contributors
87597* https://github.com/timmywil/panzoom/blob/main/MIT-License.txt
87598*/
87599(function (global, factory) {
87600     true ? module.exports = factory() :
87601    typeof define === 'function' && define.amd ? define(factory) :
87602    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Panzoom = factory());
87603}(this, (function () { 'use strict';
87604
87605    /*! *****************************************************************************
87606    Copyright (c) Microsoft Corporation.
87607
87608    Permission to use, copy, modify, and/or distribute this software for any
87609    purpose with or without fee is hereby granted.
87610
87611    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
87612    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
87613    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
87614    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
87615    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
87616    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
87617    PERFORMANCE OF THIS SOFTWARE.
87618    ***************************************************************************** */
87619
87620    var __assign = function() {
87621        __assign = Object.assign || function __assign(t) {
87622            for (var s, i = 1, n = arguments.length; i < n; i++) {
87623                s = arguments[i];
87624                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
87625            }
87626            return t;
87627        };
87628        return __assign.apply(this, arguments);
87629    };
87630
87631    /* eslint-disable no-var */
87632    if (typeof window !== 'undefined') {
87633      // Support: IE11 only
87634      if (window.NodeList && !NodeList.prototype.forEach) {
87635        NodeList.prototype.forEach = Array.prototype.forEach;
87636      }
87637      // Support: IE11 only
87638      // CustomEvent is an object instead of a constructor
87639      if (typeof window.CustomEvent !== 'function') {
87640        window.CustomEvent = function CustomEvent(event, params) {
87641          params = params || { bubbles: false, cancelable: false, detail: null };
87642          var evt = document.createEvent('CustomEvent');
87643          evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
87644          return evt
87645        };
87646      }
87647    }
87648
87649    /**
87650     * Utilites for working with multiple pointer events
87651     */
87652    function findEventIndex(pointers, event) {
87653        var i = pointers.length;
87654        while (i--) {
87655            if (pointers[i].pointerId === event.pointerId) {
87656                return i;
87657            }
87658        }
87659        return -1;
87660    }
87661    function addPointer(pointers, event) {
87662        var i;
87663        // Add touches if applicable
87664        if (event.touches) {
87665            i = 0;
87666            for (var _i = 0, _a = event.touches; _i < _a.length; _i++) {
87667                var touch = _a[_i];
87668                touch.pointerId = i++;
87669                addPointer(pointers, touch);
87670            }
87671            return;
87672        }
87673        i = findEventIndex(pointers, event);
87674        // Update if already present
87675        if (i > -1) {
87676            pointers.splice(i, 1);
87677        }
87678        pointers.push(event);
87679    }
87680    function removePointer(pointers, event) {
87681        // Add touches if applicable
87682        if (event.touches) {
87683            // Remove all touches
87684            while (pointers.length) {
87685                pointers.pop();
87686            }
87687            return;
87688        }
87689        var i = findEventIndex(pointers, event);
87690        if (i > -1) {
87691            pointers.splice(i, 1);
87692        }
87693    }
87694    /**
87695     * Calculates a center point between
87696     * the given pointer events, for panning
87697     * with multiple pointers.
87698     */
87699    function getMiddle(pointers) {
87700        // Copy to avoid changing by reference
87701        pointers = pointers.slice(0);
87702        var event1 = pointers.pop();
87703        var event2;
87704        while ((event2 = pointers.pop())) {
87705            event1 = {
87706                clientX: (event2.clientX - event1.clientX) / 2 + event1.clientX,
87707                clientY: (event2.clientY - event1.clientY) / 2 + event1.clientY
87708            };
87709        }
87710        return event1;
87711    }
87712    /**
87713     * Calculates the distance between two points
87714     * for pinch zooming.
87715     * Limits to the first 2
87716     */
87717    function getDistance(pointers) {
87718        if (pointers.length < 2) {
87719            return 0;
87720        }
87721        var event1 = pointers[0];
87722        var event2 = pointers[1];
87723        return Math.sqrt(Math.pow(Math.abs(event2.clientX - event1.clientX), 2) +
87724            Math.pow(Math.abs(event2.clientY - event1.clientY), 2));
87725    }
87726
87727    var events = {
87728        down: 'mousedown',
87729        move: 'mousemove',
87730        up: 'mouseup mouseleave'
87731    };
87732    if (typeof window !== 'undefined') {
87733        if (typeof window.PointerEvent === 'function') {
87734            events = {
87735                down: 'pointerdown',
87736                move: 'pointermove',
87737                up: 'pointerup pointerleave pointercancel'
87738            };
87739        }
87740        else if (typeof window.TouchEvent === 'function') {
87741            events = {
87742                down: 'touchstart',
87743                move: 'touchmove',
87744                up: 'touchend touchcancel'
87745            };
87746        }
87747    }
87748    function onPointer(event, elem, handler, eventOpts) {
87749        events[event].split(' ').forEach(function (name) {
87750            elem.addEventListener(name, handler, eventOpts);
87751        });
87752    }
87753    function destroyPointer(event, elem, handler) {
87754        events[event].split(' ').forEach(function (name) {
87755            elem.removeEventListener(name, handler);
87756        });
87757    }
87758
87759    var isIE = typeof document !== 'undefined' && !!document.documentMode;
87760    /**
87761     * Lazy creation of a CSS style declaration
87762     */
87763    var divStyle;
87764    function createStyle() {
87765        if (divStyle) {
87766            return divStyle;
87767        }
87768        return (divStyle = document.createElement('div').style);
87769    }
87770    /**
87771     * Proper prefixing for cross-browser compatibility
87772     */
87773    var prefixes = ['webkit', 'moz', 'ms'];
87774    var prefixCache = {};
87775    function getPrefixedName(name) {
87776        if (prefixCache[name]) {
87777            return prefixCache[name];
87778        }
87779        var divStyle = createStyle();
87780        if (name in divStyle) {
87781            return (prefixCache[name] = name);
87782        }
87783        var capName = name[0].toUpperCase() + name.slice(1);
87784        var i = prefixes.length;
87785        while (i--) {
87786            var prefixedName = "" + prefixes[i] + capName;
87787            if (prefixedName in divStyle) {
87788                return (prefixCache[name] = prefixedName);
87789            }
87790        }
87791    }
87792    /**
87793     * Gets a style value expected to be a number
87794     */
87795    function getCSSNum(name, style) {
87796        return parseFloat(style[getPrefixedName(name)]) || 0;
87797    }
87798    function getBoxStyle(elem, name, style) {
87799        if (style === void 0) { style = window.getComputedStyle(elem); }
87800        // Support: FF 68+
87801        // Firefox requires specificity for border
87802        var suffix = name === 'border' ? 'Width' : '';
87803        return {
87804            left: getCSSNum(name + "Left" + suffix, style),
87805            right: getCSSNum(name + "Right" + suffix, style),
87806            top: getCSSNum(name + "Top" + suffix, style),
87807            bottom: getCSSNum(name + "Bottom" + suffix, style)
87808        };
87809    }
87810    /**
87811     * Set a style using the properly prefixed name
87812     */
87813    function setStyle(elem, name, value) {
87814        // eslint-disable-next-line @typescript-eslint/no-explicit-any
87815        elem.style[getPrefixedName(name)] = value;
87816    }
87817    /**
87818     * Constructs the transition from panzoom options
87819     * and takes care of prefixing the transition and transform
87820     */
87821    function setTransition(elem, options) {
87822        var transform = getPrefixedName('transform');
87823        setStyle(elem, 'transition', transform + " " + options.duration + "ms " + options.easing);
87824    }
87825    /**
87826     * Set the transform using the proper prefix
87827     *
87828     * Override the transform setter.
87829     * This is exposed mostly so the user could
87830     * set other parts of a transform
87831     * aside from scale and translate.
87832     * Default is defined in src/css.ts.
87833     *
87834     * ```js
87835     * // This example always sets a rotation
87836     * // when setting the scale and translation
87837     * const panzoom = Panzoom(elem, {
87838     *   setTransform: (elem, { scale, x, y }) => {
87839     *     panzoom.setStyle('transform', `rotate(0.5turn) scale(${scale}) translate(${x}px, ${y}px)`)
87840     *   }
87841     * })
87842     * ```
87843     */
87844    function setTransform(elem, _a, _options) {
87845        var x = _a.x, y = _a.y, scale = _a.scale, isSVG = _a.isSVG;
87846        setStyle(elem, 'transform', "scale(" + scale + ") translate(" + x + "px, " + y + "px)");
87847        if (isSVG && isIE) {
87848            var matrixValue = window.getComputedStyle(elem).getPropertyValue('transform');
87849            elem.setAttribute('transform', matrixValue);
87850        }
87851    }
87852    /**
87853     * Dimensions used in containment and focal point zooming
87854     */
87855    function getDimensions(elem) {
87856        var parent = elem.parentNode;
87857        var style = window.getComputedStyle(elem);
87858        var parentStyle = window.getComputedStyle(parent);
87859        var rectElem = elem.getBoundingClientRect();
87860        var rectParent = parent.getBoundingClientRect();
87861        return {
87862            elem: {
87863                style: style,
87864                width: rectElem.width,
87865                height: rectElem.height,
87866                top: rectElem.top,
87867                bottom: rectElem.bottom,
87868                left: rectElem.left,
87869                right: rectElem.right,
87870                margin: getBoxStyle(elem, 'margin', style),
87871                border: getBoxStyle(elem, 'border', style)
87872            },
87873            parent: {
87874                style: parentStyle,
87875                width: rectParent.width,
87876                height: rectParent.height,
87877                top: rectParent.top,
87878                bottom: rectParent.bottom,
87879                left: rectParent.left,
87880                right: rectParent.right,
87881                padding: getBoxStyle(parent, 'padding', parentStyle),
87882                border: getBoxStyle(parent, 'border', parentStyle)
87883            }
87884        };
87885    }
87886
87887    /**
87888     * Determine if an element is attached to the DOM
87889     * Panzoom requires this so events work properly
87890     */
87891    function isAttached(elem) {
87892        var doc = elem.ownerDocument;
87893        var parent = elem.parentNode;
87894        return (doc &&
87895            parent &&
87896            doc.nodeType === 9 &&
87897            parent.nodeType === 1 &&
87898            doc.documentElement.contains(parent));
87899    }
87900
87901    function getClass(elem) {
87902        return (elem.getAttribute('class') || '').trim();
87903    }
87904    function hasClass(elem, className) {
87905        return elem.nodeType === 1 && (" " + getClass(elem) + " ").indexOf(" " + className + " ") > -1;
87906    }
87907    function isExcluded(elem, options) {
87908        for (var cur = elem; cur != null; cur = cur.parentNode) {
87909            if (hasClass(cur, options.excludeClass) || options.exclude.indexOf(cur) > -1) {
87910                return true;
87911            }
87912        }
87913        return false;
87914    }
87915
87916    /**
87917     * Determine if an element is SVG by checking the namespace
87918     * Exception: the <svg> element itself should be treated like HTML
87919     */
87920    var rsvg = /^http:[\w\.\/]+svg$/;
87921    function isSVGElement(elem) {
87922        return rsvg.test(elem.namespaceURI) && elem.nodeName.toLowerCase() !== 'svg';
87923    }
87924
87925    function shallowClone(obj) {
87926        var clone = {};
87927        for (var key in obj) {
87928            if (obj.hasOwnProperty(key)) {
87929                clone[key] = obj[key];
87930            }
87931        }
87932        return clone;
87933    }
87934
87935    var defaultOptions = {
87936        animate: false,
87937        canvas: false,
87938        cursor: 'move',
87939        disablePan: false,
87940        disableZoom: false,
87941        disableXAxis: false,
87942        disableYAxis: false,
87943        duration: 200,
87944        easing: 'ease-in-out',
87945        exclude: [],
87946        excludeClass: 'panzoom-exclude',
87947        handleStartEvent: function (e) {
87948            e.preventDefault();
87949            e.stopPropagation();
87950        },
87951        maxScale: 4,
87952        minScale: 0.125,
87953        overflow: 'hidden',
87954        panOnlyWhenZoomed: false,
87955        relative: false,
87956        setTransform: setTransform,
87957        startX: 0,
87958        startY: 0,
87959        startScale: 1,
87960        step: 0.3,
87961        touchAction: 'none'
87962    };
87963    function Panzoom(elem, options) {
87964        if (!elem) {
87965            throw new Error('Panzoom requires an element as an argument');
87966        }
87967        if (elem.nodeType !== 1) {
87968            throw new Error('Panzoom requires an element with a nodeType of 1');
87969        }
87970        if (!isAttached(elem)) {
87971            throw new Error('Panzoom should be called on elements that have been attached to the DOM');
87972        }
87973        options = __assign(__assign({}, defaultOptions), options);
87974        var isSVG = isSVGElement(elem);
87975        var parent = elem.parentNode;
87976        // Set parent styles
87977        parent.style.overflow = options.overflow;
87978        parent.style.userSelect = 'none';
87979        // This is important for mobile to
87980        // prevent scrolling while panning
87981        parent.style.touchAction = options.touchAction;
87982        (options.canvas ? parent : elem).style.cursor = options.cursor;
87983        // Set element styles
87984        elem.style.userSelect = 'none';
87985        elem.style.touchAction = options.touchAction;
87986        // The default for HTML is '50% 50%'
87987        // The default for SVG is '0 0'
87988        // SVG can't be changed in IE
87989        setStyle(elem, 'transformOrigin', typeof options.origin === 'string' ? options.origin : isSVG ? '0 0' : '50% 50%');
87990        function resetStyle() {
87991            parent.style.overflow = '';
87992            parent.style.userSelect = '';
87993            parent.style.touchAction = '';
87994            parent.style.cursor = '';
87995            elem.style.cursor = '';
87996            elem.style.userSelect = '';
87997            elem.style.touchAction = '';
87998            setStyle(elem, 'transformOrigin', '');
87999        }
88000        function setOptions(opts) {
88001            if (opts === void 0) { opts = {}; }
88002            for (var key in opts) {
88003                if (opts.hasOwnProperty(key)) {
88004                    options[key] = opts[key];
88005                }
88006            }
88007            // Handle option side-effects
88008            if (opts.hasOwnProperty('cursor') || opts.hasOwnProperty('canvas')) {
88009                parent.style.cursor = elem.style.cursor = '';
88010                (options.canvas ? parent : elem).style.cursor = options.cursor;
88011            }
88012            if (opts.hasOwnProperty('overflow')) {
88013                parent.style.overflow = opts.overflow;
88014            }
88015            if (opts.hasOwnProperty('touchAction')) {
88016                parent.style.touchAction = opts.touchAction;
88017                elem.style.touchAction = opts.touchAction;
88018            }
88019            if (opts.hasOwnProperty('minScale') ||
88020                opts.hasOwnProperty('maxScale') ||
88021                opts.hasOwnProperty('contain')) {
88022                setMinMax();
88023            }
88024        }
88025        var x = 0;
88026        var y = 0;
88027        var scale = 1;
88028        var isPanning = false;
88029        zoom(options.startScale, { animate: false, force: true });
88030        // Wait for scale to update
88031        // for accurate dimensions
88032        // to constrain initial values
88033        setTimeout(function () {
88034            setMinMax();
88035            pan(options.startX, options.startY, { animate: false, force: true });
88036        });
88037        function trigger(eventName, detail, opts) {
88038            if (opts.silent) {
88039                return;
88040            }
88041            var event = new CustomEvent(eventName, { detail: detail });
88042            elem.dispatchEvent(event);
88043        }
88044        function setTransformWithEvent(eventName, opts, originalEvent) {
88045            var value = { x: x, y: y, scale: scale, isSVG: isSVG, originalEvent: originalEvent };
88046            requestAnimationFrame(function () {
88047                if (typeof opts.animate === 'boolean') {
88048                    if (opts.animate) {
88049                        setTransition(elem, opts);
88050                    }
88051                    else {
88052                        setStyle(elem, 'transition', 'none');
88053                    }
88054                }
88055                opts.setTransform(elem, value, opts);
88056                trigger(eventName, value, opts);
88057                trigger('panzoomchange', value, opts);
88058            });
88059            return value;
88060        }
88061        function setMinMax() {
88062            if (options.contain) {
88063                var dims = getDimensions(elem);
88064                var parentWidth = dims.parent.width - dims.parent.border.left - dims.parent.border.right;
88065                var parentHeight = dims.parent.height - dims.parent.border.top - dims.parent.border.bottom;
88066                var elemWidth = dims.elem.width / scale;
88067                var elemHeight = dims.elem.height / scale;
88068                var elemScaledWidth = parentWidth / elemWidth;
88069                var elemScaledHeight = parentHeight / elemHeight;
88070                if (options.contain === 'inside') {
88071                    options.maxScale = Math.min(elemScaledWidth, elemScaledHeight);
88072                }
88073                else if (options.contain === 'outside') {
88074                    options.minScale = Math.max(elemScaledWidth, elemScaledHeight);
88075                }
88076            }
88077        }
88078        function constrainXY(toX, toY, toScale, panOptions) {
88079            var opts = __assign(__assign({}, options), panOptions);
88080            var result = { x: x, y: y, opts: opts };
88081            if (!opts.force && (opts.disablePan || (opts.panOnlyWhenZoomed && scale === opts.startScale))) {
88082                return result;
88083            }
88084            toX = parseFloat(toX);
88085            toY = parseFloat(toY);
88086            if (!opts.disableXAxis) {
88087                result.x = (opts.relative ? x : 0) + toX;
88088            }
88089            if (!opts.disableYAxis) {
88090                result.y = (opts.relative ? y : 0) + toY;
88091            }
88092            if (opts.contain) {
88093                var dims = getDimensions(elem);
88094                var realWidth = dims.elem.width / scale;
88095                var realHeight = dims.elem.height / scale;
88096                var scaledWidth = realWidth * toScale;
88097                var scaledHeight = realHeight * toScale;
88098                var diffHorizontal = (scaledWidth - realWidth) / 2;
88099                var diffVertical = (scaledHeight - realHeight) / 2;
88100                if (opts.contain === 'inside') {
88101                    var minX = (-dims.elem.margin.left - dims.parent.padding.left + diffHorizontal) / toScale;
88102                    var maxX = (dims.parent.width -
88103                        scaledWidth -
88104                        dims.parent.padding.left -
88105                        dims.elem.margin.left -
88106                        dims.parent.border.left -
88107                        dims.parent.border.right +
88108                        diffHorizontal) /
88109                        toScale;
88110                    result.x = Math.max(Math.min(result.x, maxX), minX);
88111                    var minY = (-dims.elem.margin.top - dims.parent.padding.top + diffVertical) / toScale;
88112                    var maxY = (dims.parent.height -
88113                        scaledHeight -
88114                        dims.parent.padding.top -
88115                        dims.elem.margin.top -
88116                        dims.parent.border.top -
88117                        dims.parent.border.bottom +
88118                        diffVertical) /
88119                        toScale;
88120                    result.y = Math.max(Math.min(result.y, maxY), minY);
88121                }
88122                else if (opts.contain === 'outside') {
88123                    var minX = (-(scaledWidth - dims.parent.width) -
88124                        dims.parent.padding.left -
88125                        dims.parent.border.left -
88126                        dims.parent.border.right +
88127                        diffHorizontal) /
88128                        toScale;
88129                    var maxX = (diffHorizontal - dims.parent.padding.left) / toScale;
88130                    result.x = Math.max(Math.min(result.x, maxX), minX);
88131                    var minY = (-(scaledHeight - dims.parent.height) -
88132                        dims.parent.padding.top -
88133                        dims.parent.border.top -
88134                        dims.parent.border.bottom +
88135                        diffVertical) /
88136                        toScale;
88137                    var maxY = (diffVertical - dims.parent.padding.top) / toScale;
88138                    result.y = Math.max(Math.min(result.y, maxY), minY);
88139                }
88140            }
88141            return result;
88142        }
88143        function constrainScale(toScale, zoomOptions) {
88144            var opts = __assign(__assign({}, options), zoomOptions);
88145            var result = { scale: scale, opts: opts };
88146            if (!opts.force && opts.disableZoom) {
88147                return result;
88148            }
88149            result.scale = Math.min(Math.max(toScale, opts.minScale), opts.maxScale);
88150            return result;
88151        }
88152        function pan(toX, toY, panOptions, originalEvent) {
88153            var result = constrainXY(toX, toY, scale, panOptions);
88154            // Only try to set if the result is somehow different
88155            if (x !== result.x || y !== result.y) {
88156                x = result.x;
88157                y = result.y;
88158                return setTransformWithEvent('panzoompan', result.opts, originalEvent);
88159            }
88160            return { x: x, y: y, scale: scale, isSVG: isSVG, originalEvent: originalEvent };
88161        }
88162        function zoom(toScale, zoomOptions, originalEvent) {
88163            var result = constrainScale(toScale, zoomOptions);
88164            var opts = result.opts;
88165            if (!opts.force && opts.disableZoom) {
88166                return;
88167            }
88168            toScale = result.scale;
88169            var toX = x;
88170            var toY = y;
88171            if (opts.focal) {
88172                // The difference between the point after the scale and the point before the scale
88173                // plus the current translation after the scale
88174                // neutralized to no scale (as the transform scale will apply to the translation)
88175                var focal = opts.focal;
88176                toX = (focal.x / toScale - focal.x / scale + x * toScale) / toScale;
88177                toY = (focal.y / toScale - focal.y / scale + y * toScale) / toScale;
88178            }
88179            var panResult = constrainXY(toX, toY, toScale, { relative: false, force: true });
88180            x = panResult.x;
88181            y = panResult.y;
88182            scale = toScale;
88183            return setTransformWithEvent('panzoomzoom', opts, originalEvent);
88184        }
88185        function zoomInOut(isIn, zoomOptions) {
88186            var opts = __assign(__assign(__assign({}, options), { animate: true }), zoomOptions);
88187            return zoom(scale * Math.exp((isIn ? 1 : -1) * opts.step), opts);
88188        }
88189        function zoomIn(zoomOptions) {
88190            return zoomInOut(true, zoomOptions);
88191        }
88192        function zoomOut(zoomOptions) {
88193            return zoomInOut(false, zoomOptions);
88194        }
88195        function zoomToPoint(toScale, point, zoomOptions, originalEvent) {
88196            var dims = getDimensions(elem);
88197            // Instead of thinking of operating on the panzoom element,
88198            // think of operating on the area inside the panzoom
88199            // element's parent
88200            // Subtract padding and border
88201            var effectiveArea = {
88202                width: dims.parent.width -
88203                    dims.parent.padding.left -
88204                    dims.parent.padding.right -
88205                    dims.parent.border.left -
88206                    dims.parent.border.right,
88207                height: dims.parent.height -
88208                    dims.parent.padding.top -
88209                    dims.parent.padding.bottom -
88210                    dims.parent.border.top -
88211                    dims.parent.border.bottom
88212            };
88213            // Adjust the clientX/clientY to ignore the area
88214            // outside the effective area
88215            var clientX = point.clientX -
88216                dims.parent.left -
88217                dims.parent.padding.left -
88218                dims.parent.border.left -
88219                dims.elem.margin.left;
88220            var clientY = point.clientY -
88221                dims.parent.top -
88222                dims.parent.padding.top -
88223                dims.parent.border.top -
88224                dims.elem.margin.top;
88225            // Adjust the clientX/clientY for HTML elements,
88226            // because they have a transform-origin of 50% 50%
88227            if (!isSVG) {
88228                clientX -= dims.elem.width / scale / 2;
88229                clientY -= dims.elem.height / scale / 2;
88230            }
88231            // Convert the mouse point from it's position over the
88232            // effective area before the scale to the position
88233            // over the effective area after the scale.
88234            var focal = {
88235                x: (clientX / effectiveArea.width) * (effectiveArea.width * toScale),
88236                y: (clientY / effectiveArea.height) * (effectiveArea.height * toScale)
88237            };
88238            return zoom(toScale, __assign(__assign({ animate: false }, zoomOptions), { focal: focal }), originalEvent);
88239        }
88240        function zoomWithWheel(event, zoomOptions) {
88241            // Need to prevent the default here
88242            // or it conflicts with regular page scroll
88243            event.preventDefault();
88244            var opts = __assign(__assign(__assign({}, options), zoomOptions), { animate: false });
88245            // Normalize to deltaX in case shift modifier is used on Mac
88246            var delta = event.deltaY === 0 && event.deltaX ? event.deltaX : event.deltaY;
88247            var wheel = delta < 0 ? 1 : -1;
88248            var toScale = constrainScale(scale * Math.exp((wheel * opts.step) / 3), opts).scale;
88249            return zoomToPoint(toScale, event, opts);
88250        }
88251        function reset(resetOptions) {
88252            var opts = __assign(__assign(__assign({}, options), { animate: true, force: true }), resetOptions);
88253            scale = constrainScale(opts.startScale, opts).scale;
88254            var panResult = constrainXY(opts.startX, opts.startY, scale, opts);
88255            x = panResult.x;
88256            y = panResult.y;
88257            return setTransformWithEvent('panzoomreset', opts);
88258        }
88259        var origX;
88260        var origY;
88261        var startClientX;
88262        var startClientY;
88263        var startScale;
88264        var startDistance;
88265        var pointers = [];
88266        function handleDown(event) {
88267            // Don't handle this event if the target is excluded
88268            if (isExcluded(event.target, options)) {
88269                return;
88270            }
88271            addPointer(pointers, event);
88272            isPanning = true;
88273            options.handleStartEvent(event);
88274            origX = x;
88275            origY = y;
88276            trigger('panzoomstart', { x: x, y: y, scale: scale, isSVG: isSVG, originalEvent: event }, options);
88277            // This works whether there are multiple
88278            // pointers or not
88279            var point = getMiddle(pointers);
88280            startClientX = point.clientX;
88281            startClientY = point.clientY;
88282            startScale = scale;
88283            startDistance = getDistance(pointers);
88284        }
88285        function move(event) {
88286            if (!isPanning ||
88287                origX === undefined ||
88288                origY === undefined ||
88289                startClientX === undefined ||
88290                startClientY === undefined) {
88291                return;
88292            }
88293            addPointer(pointers, event);
88294            var current = getMiddle(pointers);
88295            if (pointers.length > 1) {
88296                // A startDistance of 0 means
88297                // that there weren't 2 pointers
88298                // handled on start
88299                if (startDistance === 0) {
88300                    startDistance = getDistance(pointers);
88301                }
88302                // Use the distance between the first 2 pointers
88303                // to determine the current scale
88304                var diff = getDistance(pointers) - startDistance;
88305                var toScale = constrainScale((diff * options.step) / 80 + startScale).scale;
88306                zoomToPoint(toScale, current);
88307            }
88308            else {
88309                // Panning during pinch zoom can cause issues
88310                // because the zoom has not always rendered in time
88311                // for accurate calculations
88312                // See https://github.com/timmywil/panzoom/issues/512
88313                pan(origX + (current.clientX - startClientX) / scale, origY + (current.clientY - startClientY) / scale, {
88314                    animate: false
88315                }, event);
88316            }
88317        }
88318        function handleUp(event) {
88319            // Don't call panzoomend when panning with 2 touches
88320            // until both touches end
88321            if (pointers.length === 1) {
88322                trigger('panzoomend', { x: x, y: y, scale: scale, isSVG: isSVG, originalEvent: event }, options);
88323            }
88324            // Note: don't remove all pointers
88325            // Can restart without having to reinitiate all of them
88326            // Remove the pointer regardless of the isPanning state
88327            removePointer(pointers, event);
88328            if (!isPanning) {
88329                return;
88330            }
88331            isPanning = false;
88332            origX = origY = startClientX = startClientY = undefined;
88333        }
88334        var bound = false;
88335        function bind() {
88336            if (bound) {
88337                return;
88338            }
88339            bound = true;
88340            onPointer('down', options.canvas ? parent : elem, handleDown);
88341            onPointer('move', document, move, { passive: true });
88342            onPointer('up', document, handleUp, { passive: true });
88343        }
88344        function destroy() {
88345            bound = false;
88346            destroyPointer('down', options.canvas ? parent : elem, handleDown);
88347            destroyPointer('move', document, move);
88348            destroyPointer('up', document, handleUp);
88349        }
88350        if (!options.noBind) {
88351            bind();
88352        }
88353        return {
88354            bind: bind,
88355            destroy: destroy,
88356            eventNames: events,
88357            getPan: function () { return ({ x: x, y: y }); },
88358            getScale: function () { return scale; },
88359            getOptions: function () { return shallowClone(options); },
88360            pan: pan,
88361            reset: reset,
88362            resetStyle: resetStyle,
88363            setOptions: setOptions,
88364            setStyle: function (name, value) { return setStyle(elem, name, value); },
88365            zoom: zoom,
88366            zoomIn: zoomIn,
88367            zoomOut: zoomOut,
88368            zoomToPoint: zoomToPoint,
88369            zoomWithWheel: zoomWithWheel
88370        };
88371    }
88372    Panzoom.defaultOptions = defaultOptions;
88373
88374    return Panzoom;
88375
88376})));
88377
88378
88379/***/ }),
88380/* 265 */
88381/***/ (function(module, exports, __webpack_require__) {
88382
88383var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
88384 * jQuery UI Draggable 1.13.0
88385 * http://jqueryui.com
88386 *
88387 * Copyright jQuery Foundation and other contributors
88388 * Released under the MIT license.
88389 * http://jquery.org/license
88390 */
88391
88392//>>label: Draggable
88393//>>group: Interactions
88394//>>description: Enables dragging functionality for any element.
88395//>>docs: http://api.jqueryui.com/draggable/
88396//>>demos: http://jqueryui.com/draggable/
88397//>>css.structure: ../../themes/base/draggable.css
88398
88399( function( factory ) {
88400	"use strict";
88401
88402	if ( true ) {
88403
88404		// AMD. Register as an anonymous module.
88405		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
88406			__webpack_require__(2),
88407			__webpack_require__(266),
88408			__webpack_require__(268),
88409			__webpack_require__(269),
88410			__webpack_require__(270),
88411			__webpack_require__(271),
88412			__webpack_require__(272),
88413			__webpack_require__(5),
88414			__webpack_require__(150)
88415		], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
88416				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
88417				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
88418				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
88419	} else {
88420
88421		// Browser globals
88422		factory( jQuery );
88423	}
88424} )( function( $ ) {
88425"use strict";
88426
88427$.widget( "ui.draggable", $.ui.mouse, {
88428	version: "1.13.0
vendor: 8,684 bytes, lines 88428-88774
88428",
88429	widgetEventPrefix: "drag",
88430	options: {
88431		addClasses: true,
88432		appendTo: "parent",
88433		axis: false,
88434		connectToSortable: false,
88435		containment: false,
88436		cursor: "auto",
88437		cursorAt: false,
88438		grid: false,
88439		handle: false,
88440		helper: "original",
88441		iframeFix: false,
88442		opacity: false,
88443		refreshPositions: false,
88444		revert: false,
88445		revertDuration: 500,
88446		scope: "default",
88447		scroll: true,
88448		scrollSensitivity: 20,
88449		scrollSpeed: 20,
88450		snap: false,
88451		snapMode: "both",
88452		snapTolerance: 20,
88453		stack: false,
88454		zIndex: false,
88455
88456		// Callbacks
88457		drag: null,
88458		start: null,
88459		stop: null
88460	},
88461	_create: function() {
88462
88463		if ( this.options.helper === "original" ) {
88464			this._setPositionRelative();
88465		}
88466		if ( this.options.addClasses ) {
88467			this._addClass( "ui-draggable" );
88468		}
88469		this._setHandleClassName();
88470
88471		this._mouseInit();
88472	},
88473
88474	_setOption: function( key, value ) {
88475		this._super( key, value );
88476		if ( key === "handle" ) {
88477			this._removeHandleClassName();
88478			this._setHandleClassName();
88479		}
88480	},
88481
88482	_destroy: function() {
88483		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
88484			this.destroyOnClear = true;
88485			return;
88486		}
88487		this._removeHandleClassName();
88488		this._mouseDestroy();
88489	},
88490
88491	_mouseCapture: function( event ) {
88492		var o = this.options;
88493
88494		// Among others, prevent a drag on a resizable-handle
88495		if ( this.helper || o.disabled ||
88496				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
88497			return false;
88498		}
88499
88500		//Quit if we're not on a valid handle
88501		this.handle = this._getHandle( event );
88502		if ( !this.handle ) {
88503			return false;
88504		}
88505
88506		this._blurActiveElement( event );
88507
88508		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
88509
88510		return true;
88511
88512	},
88513
88514	_blockFrames: function( selector ) {
88515		this.iframeBlocks = this.document.find( selector ).map( function() {
88516			var iframe = $( this );
88517
88518			return $( "<div>" )
88519				.css( "position", "absolute" )
88520				.appendTo( iframe.parent() )
88521				.outerWidth( iframe.outerWidth() )
88522				.outerHeight( iframe.outerHeight() )
88523				.offset( iframe.offset() )[ 0 ];
88524		} );
88525	},
88526
88527	_unblockFrames: function() {
88528		if ( this.iframeBlocks ) {
88529			this.iframeBlocks.remove();
88530			delete this.iframeBlocks;
88531		}
88532	},
88533
88534	_blurActiveElement: function( event ) {
88535		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
88536			target = $( event.target );
88537
88538		// Don't blur if the event occurred on an element that is within
88539		// the currently focused element
88540		// See #10527, #12472
88541		if ( target.closest( activeElement ).length ) {
88542			return;
88543		}
88544
88545		// Blur any element that currently has focus, see #4261
88546		$.ui.safeBlur( activeElement );
88547	},
88548
88549	_mouseStart: function( event ) {
88550
88551		var o = this.options;
88552
88553		//Create and append the visible helper
88554		this.helper = this._createHelper( event );
88555
88556		this._addClass( this.helper, "ui-draggable-dragging" );
88557
88558		//Cache the helper size
88559		this._cacheHelperProportions();
88560
88561		//If ddmanager is used for droppables, set the global draggable
88562		if ( $.ui.ddmanager ) {
88563			$.ui.ddmanager.current = this;
88564		}
88565
88566		/*
88567		 * - Position generation -
88568		 * This block generates everything position related - it's the core of draggables.
88569		 */
88570
88571		//Cache the margins of the original element
88572		this._cacheMargins();
88573
88574		//Store the helper's css position
88575		this.cssPosition = this.helper.css( "position" );
88576		this.scrollParent = this.helper.scrollParent( true );
88577		this.offsetParent = this.helper.offsetParent();
88578		this.hasFixedAncestor = this.helper.parents().filter( function() {
88579				return $( this ).css( "position" ) === "fixed";
88580			} ).length > 0;
88581
88582		//The element's absolute position on the page minus margins
88583		this.positionAbs = this.element.offset();
88584		this._refreshOffsets( event );
88585
88586		//Generate the original position
88587		this.originalPosition = this.position = this._generatePosition( event, false );
88588		this.originalPageX = event.pageX;
88589		this.originalPageY = event.pageY;
88590
88591		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
88592		if ( o.cursorAt ) {
88593			this._adjustOffsetFromHelper( o.cursorAt );
88594		}
88595
88596		//Set a containment if given in the options
88597		this._setContainment();
88598
88599		//Trigger event + callbacks
88600		if ( this._trigger( "start", event ) === false ) {
88601			this._clear();
88602			return false;
88603		}
88604
88605		//Recache the helper size
88606		this._cacheHelperProportions();
88607
88608		//Prepare the droppable offsets
88609		if ( $.ui.ddmanager && !o.dropBehaviour ) {
88610			$.ui.ddmanager.prepareOffsets( this, event );
88611		}
88612
88613		// Execute the drag once - this causes the helper not to be visible before getting its
88614		// correct position
88615		this._mouseDrag( event, true );
88616
88617		// If the ddmanager is used for droppables, inform the manager that dragging has started
88618		// (see #5003)
88619		if ( $.ui.ddmanager ) {
88620			$.ui.ddmanager.dragStart( this, event );
88621		}
88622
88623		return true;
88624	},
88625
88626	_refreshOffsets: function( event ) {
88627		this.offset = {
88628			top: this.positionAbs.top - this.margins.top,
88629			left: this.positionAbs.left - this.margins.left,
88630			scroll: false,
88631			parent: this._getParentOffset(),
88632			relative: this._getRelativeOffset()
88633		};
88634
88635		this.offset.click = {
88636			left: event.pageX - this.offset.left,
88637			top: event.pageY - this.offset.top
88638		};
88639	},
88640
88641	_mouseDrag: function( event, noPropagation ) {
88642
88643		// reset any necessary cached properties (see #5009)
88644		if ( this.hasFixedAncestor ) {
88645			this.offset.parent = this._getParentOffset();
88646		}
88647
88648		//Compute the helpers position
88649		this.position = this._generatePosition( event, true );
88650		this.positionAbs = this._convertPositionTo( "absolute" );
88651
88652		//Call plugins and callbacks and use the resulting position if something is returned
88653		if ( !noPropagation ) {
88654			var ui = this._uiHash();
88655			if ( this._trigger( "drag", event, ui ) === false ) {
88656				this._mouseUp( new $.Event( "mouseup", event ) );
88657				return false;
88658			}
88659			this.position = ui.position;
88660		}
88661
88662		this.helper[ 0 ].style.left = this.position.left + "px";
88663		this.helper[ 0 ].style.top = this.position.top + "px";
88664
88665		if ( $.ui.ddmanager ) {
88666			$.ui.ddmanager.drag( this, event );
88667		}
88668
88669		return false;
88670	},
88671
88672	_mouseStop: function( event ) {
88673
88674		//If we are using droppables, inform the manager about the drop
88675		var that = this,
88676			dropped = false;
88677		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
88678			dropped = $.ui.ddmanager.drop( this, event );
88679		}
88680
88681		//if a drop comes from outside (a sortable)
88682		if ( this.dropped ) {
88683			dropped = this.dropped;
88684			this.dropped = false;
88685		}
88686
88687		if ( ( this.options.revert === "invalid" && !dropped ) ||
88688				( this.options.revert === "valid" && dropped ) ||
88689				this.options.revert === true || ( typeof this.options.revert === "function" &&
88690				this.options.revert.call( this.element, dropped ) )
88691		) {
88692			$( this.helper ).animate(
88693				this.originalPosition,
88694				parseInt( this.options.revertDuration, 10 ),
88695				function() {
88696					if ( that._trigger( "stop", event ) !== false ) {
88697						that._clear();
88698					}
88699				}
88700			);
88701		} else {
88702			if ( this._trigger( "stop", event ) !== false ) {
88703				this._clear();
88704			}
88705		}
88706
88707		return false;
88708	},
88709
88710	_mouseUp: function( event ) {
88711		this._unblockFrames();
88712
88713		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
88714		// (see #5003)
88715		if ( $.ui.ddmanager ) {
88716			$.ui.ddmanager.dragStop( this, event );
88717		}
88718
88719		// Only need to focus if the event occurred on the draggable itself, see #10527
88720		if ( this.handleElement.is( event.target ) ) {
88721
88722			// The interaction is over; whether or not the click resulted in a drag,
88723			// focus the element
88724			this.element.trigger( "focus" );
88725		}
88726
88727		return $.ui.mouse.prototype._mouseUp.call( this, event );
88728	},
88729
88730	cancel: function() {
88731
88732		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
88733			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
88734		} else {
88735			this._clear();
88736		}
88737
88738		return this;
88739
88740	},
88741
88742	_getHandle: function( event ) {
88743		return this.options.handle ?
88744			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
88745			true;
88746	},
88747
88748	_setHandleClassName: function() {
88749		this.handleElement = this.options.handle ?
88750			this.element.find( this.options.handle ) : this.element;
88751		this._addClass( this.handleElement, "ui-draggable-handle" );
88752	},
88753
88754	_removeHandleClassName: function() {
88755		this._removeClass( this.handleElement, "ui-draggable-handle" );
88756	},
88757
88758	_createHelper: function( event ) {
88759
88760		var o = this.options,
88761			helperIsFunction = typeof o.helper === "function",
88762			helper = helperIsFunction ?
88763				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
88764				( o.helper === "clone" ?
88765					this.element.clone().removeAttr( "id" ) :
88766					this.element );
88767
88768		if ( !helper.parents( "body" ).length ) {
88769			helper.appendTo( ( o.appendTo === "parent" ?
88770				this.element[ 0 ].parentNode :
88771				o.appendTo ) );
88772		}
88773
88774		// 
88774Http://bugs.jqueryui.com/ticket/9446
88775		// a helper function can return the original element
88776		// which wouldn't have been set to relative in _create
88777		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
88778			this._setPositionRelative();
88779		}
88780
88781		if ( helper[ 0 ] !== this.element[ 0 ] &&
88782				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
88783			helper.css( "position", "absolute" );
88784		}
88785
88786		return helper;
88787
88788	},
88789
88790	_setPositionRelative: function() {
88791		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
88792			this.element[ 0 ].style.position = "relative";
88793		}
88794	},
88795
88796	_adjustOffsetFromHelper: function( obj ) {
88797		if ( typeof obj === "string" ) {
88798			obj = obj.split( " " );
88799		}
88800		if ( Array
vendor: 14,647 bytes, lines 88800-89280
88800.isArray( obj ) ) {
88801			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
88802		}
88803		if ( "left" in obj ) {
88804			this.offset.click.left = obj.left + this.margins.left;
88805		}
88806		if ( "right" in obj ) {
88807			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
88808		}
88809		if ( "top" in obj ) {
88810			this.offset.click.top = obj.top + this.margins.top;
88811		}
88812		if ( "bottom" in obj ) {
88813			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
88814		}
88815	},
88816
88817	_isRootNode: function( element ) {
88818		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
88819	},
88820
88821	_getParentOffset: function() {
88822
88823		//Get the offsetParent and cache its position
88824		var po = this.offsetParent.offset(),
88825			document = this.document[ 0 ];
88826
88827		// This is a special case where we need to modify a offset calculated on start, since the
88828		// following happened:
88829		// 1. The position of the helper is absolute, so it's position is calculated based on the
88830		// next positioned parent
88831		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
88832		// the document, which means that the scroll is included in the initial calculation of the
88833		// offset of the parent, and never recalculated upon drag
88834		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
88835				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
88836			po.left += this.scrollParent.scrollLeft();
88837			po.top += this.scrollParent.scrollTop();
88838		}
88839
88840		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
88841			po = { top: 0, left: 0 };
88842		}
88843
88844		return {
88845			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
88846			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
88847		};
88848
88849	},
88850
88851	_getRelativeOffset: function() {
88852		if ( this.cssPosition !== "relative" ) {
88853			return { top: 0, left: 0 };
88854		}
88855
88856		var p = this.element.position(),
88857			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
88858
88859		return {
88860			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
88861				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
88862			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
88863				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
88864		};
88865
88866	},
88867
88868	_cacheMargins: function() {
88869		this.margins = {
88870			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
88871			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
88872			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
88873			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
88874		};
88875	},
88876
88877	_cacheHelperProportions: function() {
88878		this.helperProportions = {
88879			width: this.helper.outerWidth(),
88880			height: this.helper.outerHeight()
88881		};
88882	},
88883
88884	_setContainment: function() {
88885
88886		var isUserScrollable, c, ce,
88887			o = this.options,
88888			document = this.document[ 0 ];
88889
88890		this.relativeContainer = null;
88891
88892		if ( !o.containment ) {
88893			this.containment = null;
88894			return;
88895		}
88896
88897		if ( o.containment === "window" ) {
88898			this.containment = [
88899				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
88900				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
88901				$( window ).scrollLeft() + $( window ).width() -
88902					this.helperProportions.width - this.margins.left,
88903				$( window ).scrollTop() +
88904					( $( window ).height() || document.body.parentNode.scrollHeight ) -
88905					this.helperProportions.height - this.margins.top
88906			];
88907			return;
88908		}
88909
88910		if ( o.containment === "document" ) {
88911			this.containment = [
88912				0,
88913				0,
88914				$( document ).width() - this.helperProportions.width - this.margins.left,
88915				( $( document ).height() || document.body.parentNode.scrollHeight ) -
88916					this.helperProportions.height - this.margins.top
88917			];
88918			return;
88919		}
88920
88921		if ( o.containment.constructor === Array ) {
88922			this.containment = o.containment;
88923			return;
88924		}
88925
88926		if ( o.containment === "parent" ) {
88927			o.containment = this.helper[ 0 ].parentNode;
88928		}
88929
88930		c = $( o.containment );
88931		ce = c[ 0 ];
88932
88933		if ( !ce ) {
88934			return;
88935		}
88936
88937		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
88938
88939		this.containment = [
88940			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
88941				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
88942			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
88943				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
88944			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
88945				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
88946				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
88947				this.helperProportions.width -
88948				this.margins.left -
88949				this.margins.right,
88950			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
88951				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
88952				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
88953				this.helperProportions.height -
88954				this.margins.top -
88955				this.margins.bottom
88956		];
88957		this.relativeContainer = c;
88958	},
88959
88960	_convertPositionTo: function( d, pos ) {
88961
88962		if ( !pos ) {
88963			pos = this.position;
88964		}
88965
88966		var mod = d === "absolute" ? 1 : -1,
88967			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
88968
88969		return {
88970			top: (
88971
88972				// The absolute mouse position
88973				pos.top	+
88974
88975				// Only for relative positioned nodes: Relative offset from element to offset parent
88976				this.offset.relative.top * mod +
88977
88978				// The offsetParent's offset without borders (offset + border)
88979				this.offset.parent.top * mod -
88980				( ( this.cssPosition === "fixed" ?
88981					-this.offset.scroll.top :
88982					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
88983			),
88984			left: (
88985
88986				// The absolute mouse position
88987				pos.left +
88988
88989				// Only for relative positioned nodes: Relative offset from element to offset parent
88990				this.offset.relative.left * mod +
88991
88992				// The offsetParent's offset without borders (offset + border)
88993				this.offset.parent.left * mod	-
88994				( ( this.cssPosition === "fixed" ?
88995					-this.offset.scroll.left :
88996					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
88997			)
88998		};
88999
89000	},
89001
89002	_generatePosition: function( event, constrainPosition ) {
89003
89004		var containment, co, top, left,
89005			o = this.options,
89006			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
89007			pageX = event.pageX,
89008			pageY = event.pageY;
89009
89010		// Cache the scroll
89011		if ( !scrollIsRootNode || !this.offset.scroll ) {
89012			this.offset.scroll = {
89013				top: this.scrollParent.scrollTop(),
89014				left: this.scrollParent.scrollLeft()
89015			};
89016		}
89017
89018		/*
89019		 * - Position constraining -
89020		 * Constrain the position to a mix of grid, containment.
89021		 */
89022
89023		// If we are not dragging yet, we won't check for options
89024		if ( constrainPosition ) {
89025			if ( this.containment ) {
89026				if ( this.relativeContainer ) {
89027					co = this.relativeContainer.offset();
89028					containment = [
89029						this.containment[ 0 ] + co.left,
89030						this.containment[ 1 ] + co.top,
89031						this.containment[ 2 ] + co.left,
89032						this.containment[ 3 ] + co.top
89033					];
89034				} else {
89035					containment = this.containment;
89036				}
89037
89038				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
89039					pageX = containment[ 0 ] + this.offset.click.left;
89040				}
89041				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
89042					pageY = containment[ 1 ] + this.offset.click.top;
89043				}
89044				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
89045					pageX = containment[ 2 ] + this.offset.click.left;
89046				}
89047				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
89048					pageY = containment[ 3 ] + this.offset.click.top;
89049				}
89050			}
89051
89052			if ( o.grid ) {
89053
89054				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
89055				// argument errors in IE (see ticket #6950)
89056				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
89057					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
89058				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
89059					top - this.offset.click.top > containment[ 3 ] ) ?
89060						top :
89061						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
89062							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
89063
89064				left = o.grid[ 0 ] ? this.originalPageX +
89065					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
89066					this.originalPageX;
89067				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
89068					left - this.offset.click.left > containment[ 2 ] ) ?
89069						left :
89070						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
89071							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
89072			}
89073
89074			if ( o.axis === "y" ) {
89075				pageX = this.originalPageX;
89076			}
89077
89078			if ( o.axis === "x" ) {
89079				pageY = this.originalPageY;
89080			}
89081		}
89082
89083		return {
89084			top: (
89085
89086				// The absolute mouse position
89087				pageY -
89088
89089				// Click offset (relative to the element)
89090				this.offset.click.top -
89091
89092				// Only for relative positioned nodes: Relative offset from element to offset parent
89093				this.offset.relative.top -
89094
89095				// The offsetParent's offset without borders (offset + border)
89096				this.offset.parent.top +
89097				( this.cssPosition === "fixed" ?
89098					-this.offset.scroll.top :
89099					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
89100			),
89101			left: (
89102
89103				// The absolute mouse position
89104				pageX -
89105
89106				// Click offset (relative to the element)
89107				this.offset.click.left -
89108
89109				// Only for relative positioned nodes: Relative offset from element to offset parent
89110				this.offset.relative.left -
89111
89112				// The offsetParent's offset without borders (offset + border)
89113				this.offset.parent.left +
89114				( this.cssPosition === "fixed" ?
89115					-this.offset.scroll.left :
89116					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
89117			)
89118		};
89119
89120	},
89121
89122	_clear: function() {
89123		this._removeClass( this.helper, "ui-draggable-dragging" );
89124		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
89125			this.helper.remove();
89126		}
89127		this.helper = null;
89128		this.cancelHelperRemoval = false;
89129		if ( this.destroyOnClear ) {
89130			this.destroy();
89131		}
89132	},
89133
89134	// From now on bulk stuff - mainly helpers
89135
89136	_trigger: function( type, event, ui ) {
89137		ui = ui || this._uiHash();
89138		$.ui.plugin.call( this, type, [ event, ui, this ], true );
89139
89140		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
89141		if ( /^(drag|start|stop)/.test( type ) ) {
89142			this.positionAbs = this._convertPositionTo( "absolute" );
89143			ui.offset = this.positionAbs;
89144		}
89145		return $.Widget.prototype._trigger.call( this, type, event, ui );
89146	},
89147
89148	plugins: {},
89149
89150	_uiHash: function() {
89151		return {
89152			helper: this.helper,
89153			position: this.position,
89154			originalPosition: this.originalPosition,
89155			offset: this.positionAbs
89156		};
89157	}
89158
89159} );
89160
89161$.ui.plugin.add( "draggable", "connectToSortable", {
89162	start: function( event, ui, draggable ) {
89163		var uiSortable = $.extend( {}, ui, {
89164			item: draggable.element
89165		} );
89166
89167		draggable.sortables = [];
89168		$( draggable.options.connectToSortable ).each( function() {
89169			var sortable = $( this ).sortable( "instance" );
89170
89171			if ( sortable && !sortable.options.disabled ) {
89172				draggable.sortables.push( sortable );
89173
89174				// RefreshPositions is called at drag start to refresh the containerCache
89175				// which is used in drag. This ensures it's initialized and synchronized
89176				// with any changes that might have happened on the page since initialization.
89177				sortable.refreshPositions();
89178				sortable._trigger( "activate", event, uiSortable );
89179			}
89180		} );
89181	},
89182	stop: function( event, ui, draggable ) {
89183		var uiSortable = $.extend( {}, ui, {
89184			item: draggable.element
89185		} );
89186
89187		draggable.cancelHelperRemoval = false;
89188
89189		$.each( draggable.sortables, function() {
89190			var sortable = this;
89191
89192			if ( sortable.isOver ) {
89193				sortable.isOver = 0;
89194
89195				// Allow this sortable to handle removing the helper
89196				draggable.cancelHelperRemoval = true;
89197				sortable.cancelHelperRemoval = false;
89198
89199				// Use _storedCSS To restore properties in the sortable,
89200				// as this also handles revert (#9675) since the draggable
89201				// may have modified them in unexpected ways (#8809)
89202				sortable._storedCSS = {
89203					position: sortable.placeholder.css( "position" ),
89204					top: sortable.placeholder.css( "top" ),
89205					left: sortable.placeholder.css( "left" )
89206				};
89207
89208				sortable._mouseStop( event );
89209
89210				// Once drag has ended, the sortable should return to using
89211				// its original helper, not the shared helper from draggable
89212				sortable.options.helper = sortable.options._helper;
89213			} else {
89214
89215				// Prevent this Sortable from removing the helper.
89216				// However, don't set the draggable to remove the helper
89217				// either as another connected Sortable may yet handle the removal.
89218				sortable.cancelHelperRemoval = true;
89219
89220				sortable._trigger( "deactivate", event, uiSortable );
89221			}
89222		} );
89223	},
89224	drag: function( event, ui, draggable ) {
89225		$.each( draggable.sortables, function() {
89226			var innermostIntersecting = false,
89227				sortable = this;
89228
89229			// Copy over variables that sortable's _intersectsWith uses
89230			sortable.positionAbs = draggable.positionAbs;
89231			sortable.helperProportions = draggable.helperProportions;
89232			sortable.offset.click = draggable.offset.click;
89233
89234			if ( sortable._intersectsWith( sortable.containerCache ) ) {
89235				innermostIntersecting = true;
89236
89237				$.each( draggable.sortables, function() {
89238
89239					// Copy over variables that sortable's _intersectsWith uses
89240					this.positionAbs = draggable.positionAbs;
89241					this.helperProportions = draggable.helperProportions;
89242					this.offset.click = draggable.offset.click;
89243
89244					if ( this !== sortable &&
89245							this._intersectsWith( this.containerCache ) &&
89246							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
89247						innermostIntersecting = false;
89248					}
89249
89250					return innermostIntersecting;
89251				} );
89252			}
89253
89254			if ( innermostIntersecting ) {
89255
89256				// If it intersects, we use a little isOver variable and set it once,
89257				// so that the move-in stuff gets fired only once.
89258				if ( !sortable.isOver ) {
89259					sortable.isOver = 1;
89260
89261					// Store draggable's parent in case we need to reappend to it later.
89262					draggable._parent = ui.helper.parent();
89263
89264					sortable.currentItem = ui.helper
89265						.appendTo( sortable.element )
89266						.data( "ui-sortable-item", true );
89267
89268					// Store helper option to later restore it
89269					sortable.options._helper = sortable.options.helper;
89270
89271					sortable.options.helper = function() {
89272						return ui.helper[ 0 ];
89273					};
89274
89275					// Fire the start events of the sortable with our passed browser event,
89276					// and our own helper (so it doesn't create a new one)
89277					event.target = sortable.currentItem[ 0 ];
89278					sortable._mouseCapture( event, true );
89279					sortable._mouseStart( event, true, true );
89280
vendor: 10,561 bytes, lines 89281-89641
89281					// Because the browser event is way off the new appended portlet,
89282					// modify necessary variables to reflect the changes
89283					sortable.offset.click.top = draggable.offset.click.top;
89284					sortable.offset.click.left = draggable.offset.click.left;
89285					sortable.offset.parent.left -= draggable.offset.parent.left -
89286						sortable.offset.parent.left;
89287					sortable.offset.parent.top -= draggable.offset.parent.top -
89288						sortable.offset.parent.top;
89289
89290					draggable._trigger( "toSortable", event );
89291
89292					// Inform draggable that the helper is in a valid drop zone,
89293					// used solely in the revert option to handle "valid/invalid".
89294					draggable.dropped = sortable.element;
89295
89296					// Need to refreshPositions of all sortables in the case that
89297					// adding to one sortable changes the location of the other sortables (#9675)
89298					$.each( draggable.sortables, function() {
89299						this.refreshPositions();
89300					} );
89301
89302					// Hack so receive/update callbacks work (mostly)
89303					draggable.currentItem = draggable.element;
89304					sortable.fromOutside = draggable;
89305				}
89306
89307				if ( sortable.currentItem ) {
89308					sortable._mouseDrag( event );
89309
89310					// Copy the sortable's position because the draggable's can potentially reflect
89311					// a relative position, while sortable is always absolute, which the dragged
89312					// element has now become. (#8809)
89313					ui.position = sortable.position;
89314				}
89315			} else {
89316
89317				// If it doesn't intersect with the sortable, and it intersected before,
89318				// we fake the drag stop of the sortable, but make sure it doesn't remove
89319				// the helper by using cancelHelperRemoval.
89320				if ( sortable.isOver ) {
89321
89322					sortable.isOver = 0;
89323					sortable.cancelHelperRemoval = true;
89324
89325					// Calling sortable's mouseStop would trigger a revert,
89326					// so revert must be temporarily false until after mouseStop is called.
89327					sortable.options._revert = sortable.options.revert;
89328					sortable.options.revert = false;
89329
89330					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
89331					sortable._mouseStop( event, true );
89332
89333					// Restore sortable behaviors that were modfied
89334					// when the draggable entered the sortable area (#9481)
89335					sortable.options.revert = sortable.options._revert;
89336					sortable.options.helper = sortable.options._helper;
89337
89338					if ( sortable.placeholder ) {
89339						sortable.placeholder.remove();
89340					}
89341
89342					// Restore and recalculate the draggable's offset considering the sortable
89343					// may have modified them in unexpected ways. (#8809, #10669)
89344					ui.helper.appendTo( draggable._parent );
89345					draggable._refreshOffsets( event );
89346					ui.position = draggable._generatePosition( event, true );
89347
89348					draggable._trigger( "fromSortable", event );
89349
89350					// Inform draggable that the helper is no longer in a valid drop zone
89351					draggable.dropped = false;
89352
89353					// Need to refreshPositions of all sortables just in case removing
89354					// from one sortable changes the location of other sortables (#9675)
89355					$.each( draggable.sortables, function() {
89356						this.refreshPositions();
89357					} );
89358				}
89359			}
89360		} );
89361	}
89362} );
89363
89364$.ui.plugin.add( "draggable", "cursor", {
89365	start: function( event, ui, instance ) {
89366		var t = $( "body" ),
89367			o = instance.options;
89368
89369		if ( t.css( "cursor" ) ) {
89370			o._cursor = t.css( "cursor" );
89371		}
89372		t.css( "cursor", o.cursor );
89373	},
89374	stop: function( event, ui, instance ) {
89375		var o = instance.options;
89376		if ( o._cursor ) {
89377			$( "body" ).css( "cursor", o._cursor );
89378		}
89379	}
89380} );
89381
89382$.ui.plugin.add( "draggable", "opacity", {
89383	start: function( event, ui, instance ) {
89384		var t = $( ui.helper ),
89385			o = instance.options;
89386		if ( t.css( "opacity" ) ) {
89387			o._opacity = t.css( "opacity" );
89388		}
89389		t.css( "opacity", o.opacity );
89390	},
89391	stop: function( event, ui, instance ) {
89392		var o = instance.options;
89393		if ( o._opacity ) {
89394			$( ui.helper ).css( "opacity", o._opacity );
89395		}
89396	}
89397} );
89398
89399$.ui.plugin.add( "draggable", "scroll", {
89400	start: function( event, ui, i ) {
89401		if ( !i.scrollParentNotHidden ) {
89402			i.scrollParentNotHidden = i.helper.scrollParent( false );
89403		}
89404
89405		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
89406				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
89407			i.overflowOffset = i.scrollParentNotHidden.offset();
89408		}
89409	},
89410	drag: function( event, ui, i  ) {
89411
89412		var o = i.options,
89413			scrolled = false,
89414			scrollParent = i.scrollParentNotHidden[ 0 ],
89415			document = i.document[ 0 ];
89416
89417		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
89418			if ( !o.axis || o.axis !== "x" ) {
89419				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
89420						o.scrollSensitivity ) {
89421					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
89422				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
89423					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
89424				}
89425			}
89426
89427			if ( !o.axis || o.axis !== "y" ) {
89428				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
89429						o.scrollSensitivity ) {
89430					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
89431				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
89432					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
89433				}
89434			}
89435
89436		} else {
89437
89438			if ( !o.axis || o.axis !== "x" ) {
89439				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
89440					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
89441				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
89442						o.scrollSensitivity ) {
89443					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
89444				}
89445			}
89446
89447			if ( !o.axis || o.axis !== "y" ) {
89448				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
89449					scrolled = $( document ).scrollLeft(
89450						$( document ).scrollLeft() - o.scrollSpeed
89451					);
89452				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
89453						o.scrollSensitivity ) {
89454					scrolled = $( document ).scrollLeft(
89455						$( document ).scrollLeft() + o.scrollSpeed
89456					);
89457				}
89458			}
89459
89460		}
89461
89462		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
89463			$.ui.ddmanager.prepareOffsets( i, event );
89464		}
89465
89466	}
89467} );
89468
89469$.ui.plugin.add( "draggable", "snap", {
89470	start: function( event, ui, i ) {
89471
89472		var o = i.options;
89473
89474		i.snapElements = [];
89475
89476		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
89477			.each( function() {
89478				var $t = $( this ),
89479					$o = $t.offset();
89480				if ( this !== i.element[ 0 ] ) {
89481					i.snapElements.push( {
89482						item: this,
89483						width: $t.outerWidth(), height: $t.outerHeight(),
89484						top: $o.top, left: $o.left
89485					} );
89486				}
89487			} );
89488
89489	},
89490	drag: function( event, ui, inst ) {
89491
89492		var ts, bs, ls, rs, l, r, t, b, i, first,
89493			o = inst.options,
89494			d = o.snapTolerance,
89495			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
89496			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
89497
89498		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
89499
89500			l = inst.snapElements[ i ].left - inst.margins.left;
89501			r = l + inst.snapElements[ i ].width;
89502			t = inst.snapElements[ i ].top - inst.margins.top;
89503			b = t + inst.snapElements[ i ].height;
89504
89505			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
89506					!$.contains( inst.snapElements[ i ].item.ownerDocument,
89507					inst.snapElements[ i ].item ) ) {
89508				if ( inst.snapElements[ i ].snapping ) {
89509					if ( inst.options.snap.release ) {
89510						inst.options.snap.release.call(
89511							inst.element,
89512							event,
89513							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
89514						);
89515					}
89516				}
89517				inst.snapElements[ i ].snapping = false;
89518				continue;
89519			}
89520
89521			if ( o.snapMode !== "inner" ) {
89522				ts = Math.abs( t - y2 ) <= d;
89523				bs = Math.abs( b - y1 ) <= d;
89524				ls = Math.abs( l - x2 ) <= d;
89525				rs = Math.abs( r - x1 ) <= d;
89526				if ( ts ) {
89527					ui.position.top = inst._convertPositionTo( "relative", {
89528						top: t - inst.helperProportions.height,
89529						left: 0
89530					} ).top;
89531				}
89532				if ( bs ) {
89533					ui.position.top = inst._convertPositionTo( "relative", {
89534						top: b,
89535						left: 0
89536					} ).top;
89537				}
89538				if ( ls ) {
89539					ui.position.left = inst._convertPositionTo( "relative", {
89540						top: 0,
89541						left: l - inst.helperProportions.width
89542					} ).left;
89543				}
89544				if ( rs ) {
89545					ui.position.left = inst._convertPositionTo( "relative", {
89546						top: 0,
89547						left: r
89548					} ).left;
89549				}
89550			}
89551
89552			first = ( ts || bs || ls || rs );
89553
89554			if ( o.snapMode !== "outer" ) {
89555				ts = Math.abs( t - y1 ) <= d;
89556				bs = Math.abs( b - y2 ) <= d;
89557				ls = Math.abs( l - x1 ) <= d;
89558				rs = Math.abs( r - x2 ) <= d;
89559				if ( ts ) {
89560					ui.position.top = inst._convertPositionTo( "relative", {
89561						top: t,
89562						left: 0
89563					} ).top;
89564				}
89565				if ( bs ) {
89566					ui.position.top = inst._convertPositionTo( "relative", {
89567						top: b - inst.helperProportions.height,
89568						left: 0
89569					} ).top;
89570				}
89571				if ( ls ) {
89572					ui.position.left = inst._convertPositionTo( "relative", {
89573						top: 0,
89574						left: l
89575					} ).left;
89576				}
89577				if ( rs ) {
89578					ui.position.left = inst._convertPositionTo( "relative", {
89579						top: 0,
89580						left: r - inst.helperProportions.width
89581					} ).left;
89582				}
89583			}
89584
89585			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
89586				if ( inst.options.snap.snap ) {
89587					inst.options.snap.snap.call(
89588						inst.element,
89589						event,
89590						$.extend( inst._uiHash(), {
89591							snapItem: inst.snapElements[ i ].item
89592						} ) );
89593				}
89594			}
89595			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
89596
89597		}
89598
89599	}
89600} );
89601
89602$.ui.plugin.add( "draggable", "stack", {
89603	start: function( event, ui, instance ) {
89604		var min,
89605			o = instance.options,
89606			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
89607				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
89608					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
89609			} );
89610
89611		if ( !group.length ) {
89612			return;
89613		}
89614
89615		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
89616		$( group ).each( function( i ) {
89617			$( this ).css( "zIndex", min + i );
89618		} );
89619		this.css( "zIndex", ( min + group.length ) );
89620	}
89621} );
89622
89623$.ui.plugin.add( "draggable", "zIndex", {
89624	start: function( event, ui, instance ) {
89625		var t = $( ui.helper ),
89626			o = instance.options;
89627
89628		if ( t.css( "zIndex" ) ) {
89629			o._zIndex = t.css( "zIndex" );
89630		}
89631		t.css( "zIndex", o.zIndex );
89632	},
89633	stop: function( event, ui, instance ) {
89634		var o = instance.options;
89635
89636		if ( o._zIndex ) {
89637			$( ui.helper ).css( "zIndex", o._zIndex );
89638		}
89639	}
89640} );
89641
89642return $.ui.draggable;
89643
89644} );
89645
89646
89647/***/ }),
89648/* 266 */
89649/***/ (function(module, exports, __webpack_require__) {
89650
89651var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
89652 * jQuery UI Mouse 1.13.0
89653 * http://jqueryui.com
89654 *
89655 * Copyright jQuery Foundation and other contributors
89656 * Released under the MIT license.
89657 * http://jquery.org/license
89658 */
89659
89660//>>label: Mouse
89661//>>group: Widgets
89662//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
89663//>>docs: http://api.jqueryui.com/mouse/
89664
89665( function( factory ) {
89666	"use strict";
89667
89668	if ( true ) {
89669
89670		// AMD. Register as an anonymous module.
89671		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
89672			__webpack_require__(2),
89673			__webpack_require__(267),
89674			__webpack_require__(5),
89675			__webpack_require__(150)
89676		], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
89677				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
89678				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
89679				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
89680	} else {
89681
89682		// Browser globals
89683		factory( jQuery );
89684	}
89685} )( function( $ ) {
89686"use strict";
89687
89688var mouseHandled = false;
vendor: 4,602 bytes, lines 89689-89850
89689$( document ).on( "mouseup", function() {
89690	mouseHandled = false;
89691} );
89692
89693return $.widget( "ui.mouse", {
89694	version: "1.13.0",
89695	options: {
89696		cancel: "input, textarea, button, select, option",
89697		distance: 1,
89698		delay: 0
89699	},
89700	_mouseInit: function() {
89701		var that = this;
89702
89703		this.element
89704			.on( "mousedown." + this.widgetName, function( event ) {
89705				return that._mouseDown( event );
89706			} )
89707			.on( "click." + this.widgetName, function( event ) {
89708				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
89709					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
89710					event.stopImmediatePropagation();
89711					return false;
89712				}
89713			} );
89714
89715		this.started = false;
89716	},
89717
89718	// TODO: make sure destroying one instance of mouse doesn't mess with
89719	// other instances of mouse
89720	_mouseDestroy: function() {
89721		this.element.off( "." + this.widgetName );
89722		if ( this._mouseMoveDelegate ) {
89723			this.document
89724				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
89725				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
89726		}
89727	},
89728
89729	_mouseDown: function( event ) {
89730
89731		// don't let more than one widget handle mouseStart
89732		if ( mouseHandled ) {
89733			return;
89734		}
89735
89736		this._mouseMoved = false;
89737
89738		// We may have missed mouseup (out of window)
89739		if ( this._mouseStarted ) {
89740			this._mouseUp( event );
89741		}
89742
89743		this._mouseDownEvent = event;
89744
89745		var that = this,
89746			btnIsLeft = ( event.which === 1 ),
89747
89748			// event.target.nodeName works around a bug in IE 8 with
89749			// disabled inputs (#7620)
89750			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
89751				$( event.target ).closest( this.options.cancel ).length : false );
89752		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
89753			return true;
89754		}
89755
89756		this.mouseDelayMet = !this.options.delay;
89757		if ( !this.mouseDelayMet ) {
89758			this._mouseDelayTimer = setTimeout( function() {
89759				that.mouseDelayMet = true;
89760			}, this.options.delay );
89761		}
89762
89763		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
89764			this._mouseStarted = ( this._mouseStart( event ) !== false );
89765			if ( !this._mouseStarted ) {
89766				event.preventDefault();
89767				return true;
89768			}
89769		}
89770
89771		// Click event may never have fired (Gecko & Opera)
89772		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
89773			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
89774		}
89775
89776		// These delegates are required to keep context
89777		this._mouseMoveDelegate = function( event ) {
89778			return that._mouseMove( event );
89779		};
89780		this._mouseUpDelegate = function( event ) {
89781			return that._mouseUp( event );
89782		};
89783
89784		this.document
89785			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
89786			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
89787
89788		event.preventDefault();
89789
89790		mouseHandled = true;
89791		return true;
89792	},
89793
89794	_mouseMove: function( event ) {
89795
89796		// Only check for mouseups outside the document if you've moved inside the document
89797		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
89798		// fire a mousemove event if content is placed under the cursor. See #7778
89799		// Support: IE <9
89800		if ( this._mouseMoved ) {
89801
89802			// IE mouseup check - mouseup happened when mouse was out of window
89803			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
89804					!event.button ) {
89805				return this._mouseUp( event );
89806
89807			// Iframe mouseup check - mouseup occurred in another document
89808			} else if ( !event.which ) {
89809
89810				// Support: Safari <=8 - 9
89811				// Safari sets which to 0 if you press any of the following keys
89812				// during a drag (#14461)
89813				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
89814						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
89815					this.ignoreMissingWhich = true;
89816				} else if ( !this.ignoreMissingWhich ) {
89817					return this._mouseUp( event );
89818				}
89819			}
89820		}
89821
89822		if ( event.which || event.button ) {
89823			this._mouseMoved = true;
89824		}
89825
89826		if ( this._mouseStarted ) {
89827			this._mouseDrag( event );
89828			return event.preventDefault();
89829		}
89830
89831		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
89832			this._mouseStarted =
89833				( this._mouseStart( this._mouseDownEvent, event ) !== false );
89834			if ( this._mouseStarted ) {
89835				this._mouseDrag( event );
89836			} else {
89837				this._mouseUp( event );
89838			}
89839		}
89840
89841		return !this._mouseStarted;
89842	},
89843
89844	_mouseUp: function( event ) {
89845		this.document
89846			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
89847			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
89848
89849		if ( this._mouseStarted ) {
89850			this._mouseStarted = false;
89851
89852			if ( event.target === this._mouseDownEvent.target ) {
89853				$.data( event.target, this.widgetName + ".preventClickEvent", true );
89854			}
89855
89856			this._mouseStop( event );
89857		}
89858
89859		if ( this._mouseDelayTimer ) {
89860			clearTimeout( this._mouseDelayTimer );
89861			delete this._mouseDelayTimer;
89862		}
89863
89864		this.ignoreMissingWhich = false;
89865		mouseHandled = false;
89866		event.preventDefault();
89867	},
89868
89869	_mouseDistanceMet: function( event ) {
89870		return ( Math.max(
89871				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
89872				Math.abs( this._mouseDownEvent.pageY - event.pageY )
89873			) >= this.options.distance
89874		);
89875	},
89876
89877	_mouseDelayMet: function( /* event */ ) {
89878		return this.mouseDelayMet;
89879	},
89880
89881	// These are placeholder methods, to be overriden by extending plugin
89882	_mouseStart: function( /* event */ ) {},
89883	_mouseDrag: function( /* event */ ) {},
89884	_mouseStop: function( /* event */ ) {},
89885	_mouseCapture: function( /* event */ ) {
89886		return true;
89887	}
89888} );
89889
89890} );
89891
89892
89893/***/ }),
89894/* 267 */
89895/***/ (function(module, exports, __webpack_require__) {
89896
89897var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
89898	"use strict";
89899
89900	if ( true ) {
89901
89902		// AMD. Register as an anonymous module.
89903		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2), __webpack_require__(5) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
89904				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
89905				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
89906				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
89907	} else {
89908
89909		// Browser globals
89910		factory( jQuery );
89911	}
89912} )( function( $ ) {
89913"use strict";
89914
89915// This file is deprecated
89916return $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
89917} );
89918
89919
89920/***/ }),
89921/* 268 */
89922/***/ (function(module, exports, __webpack_require__) {
89923
89924var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
89925 * jQuery UI :data 1.13.0
89926 * http://jqueryui.com
89927 *
89928 * Copyright jQuery Foundation and other contributors
89929 * Released under the MIT license.
89930 * http://jquery.org/license
89931 */
89932
89933//>>label: :data Selector
89934//>>group: Core
89935//>>description: Selects elements which have data stored under the specified key.
89936//>>docs: http://api.jqueryui.com/data-selector/
89937
89938( function( factory ) {
89939	"use strict";
89940
89941	if ( true ) {
89942
89943		// AMD. Register as an anonymous module.
89944		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2), __webpack_require__(5) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
89945				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
89946				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
89947				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
89948	} else {
89949
89950		// Browser globals
89951		factory( jQuery );
89952	}
89953} )( function( $ ) {
89954"use strict";
89955
89956return $.extend( $.expr.pseudos, {
89957	data: $.expr.createPseudo ?
89958		$.expr.createPseudo( function( dataName ) {
89959			return function( elem ) {
89960				return !!$.data( elem, dataName );
89961			};
89962		} ) :
89963
89964		// Support: jQuery <1.8
89965		function( elem, i, match ) {
89966			return !!$.data( elem, match[ 3 ] );
89967		}
89968} );
89969} );
89970
89971
89972/***/ }),
89973/* 269 */
89974/***/ (function(module, exports, __webpack_require__) {
89975
89976var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
89977	"use strict";
89978
89979	if ( true ) {
89980
89981		// AMD. Register as an anonymous module.
89982		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2), __webpack_require__(5) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
89983				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
89984				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
89985				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
89986	} else {
89987
89988		// Browser globals
89989		factory( jQuery );
89990	}
89991} )( function( $ ) {
89992"use strict";
89993
89994// $.ui.plugin is deprecated. Use $.widget() extensions instead.
89995return $.ui.plugin = {
89996	add: function( module, option, set ) {
89997		var i,
89998			proto = $.ui[ module ].prototype;
89999		for ( i in set ) {
90000			proto.plugins[ i ] = proto.plugins[ i ] || [];
90001			proto.plugins[ i ].push( [ option, set[ i ] ] );
90002		}
90003	},
90004	call: function( instance, name, args, allowDisconnected ) {
90005		var i,
90006			set = instance.plugins[ name ];
90007
90008		if ( !set ) {
90009			return;
90010		}
90011
90012		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
90013				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
90014			return;
90015		}
90016
90017		for ( i = 0; i < set.length; i++ ) {
90018			if ( instance.options[ set[ i ][ 0 ] ] ) {
90019				set[ i ][ 1 ].apply( instance.element, args );
90020			}
90021		}
90022	}
90023};
90024
90025} );
90026
90027
90028/***/ }),
90029/* 270 */
90030/***/ (function(module, exports, __webpack_require__) {
90031
90032var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
90033	"use strict";
90034
90035	if ( true ) {
90036
90037		// AMD. Register as an anonymous module.
90038		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2), __webpack_require__(5) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
90039				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
90040				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
90041				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
90042	} else {
90043
90044		// Browser globals
90045		factory( jQuery );
90046	}
90047} )( function( $ ) {
90048"use strict";
90049
90050return $.ui.safeActiveElement = function( document ) {
90051	var activeElement;
90052
90053	// Support: IE 9 only
90054	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
90055	try {
90056		activeElement = document.activeElement;
90057	} catch ( error ) {
90058		activeElement = document.body;
90059	}
90060
90061	// Support: IE 9 - 11 only
90062	// IE may return null instead of an element
90063	// Interestingly, this only seems to occur when NOT in an iframe
90064	if ( !activeElement ) {
90065		activeElement = document.body;
90066	}
90067
90068	// Support: IE 11 only
90069	// IE11 returns a seemingly empty object in some cases when accessing
90070	// document.activeElement from an <iframe>
90071	if ( !activeElement.nodeName ) {
90072		activeElement = document.body;
90073	}
90074
90075	return activeElement;
90076};
90077
90078} );
90079
90080
90081/***/ }),
90082/* 271 */
90083/***/ (function(module, exports, __webpack_require__) {
90084
90085var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;( function( factory ) {
90086	"use strict";
90087
90088	if ( true ) {
90089
90090		// AMD. Register as an anonymous module.
90091		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2), __webpack_require__(5) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
90092				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
90093				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
90094				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
90095	} else {
90096
90097		// Browser globals
90098		factory( jQuery );
90099	}
90100} )( function( $ ) {
90101"use strict";
90102
90103return $.ui.safeBlur = function( element ) {
90104
90105	// Support: IE9 - 10 only
90106	// If the <body> is blurred, IE will switch windows, see #9420
90107	if ( element && element.nodeName.toLowerCase() !== "body" ) {
90108		$( element ).trigger( "blur" );
90109	}
90110};
90111
90112} );
90113
90114
90115/***/ }),
90116/* 272 */
90117/***/ (function(module, exports, __webpack_require__) {
90118
90119var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
90120 * jQuery UI Scroll Parent 1.13.0
90121 * http://jqueryui.com
90122 *
90123 * Copyright jQuery Foundation and other contributors
90124 * Released under the MIT license.
90125 * http://jquery.org/license
90126 */
90127
90128//>>label: scrollParent
90129//>>group: Core
90130//>>description: Get the closest ancestor element that is scrollable.
90131//>>docs: http://api.jqueryui.com/scrollParent/
90132
90133( function( factory ) {
90134	"use strict";
90135
90136	if ( true ) {
90137
90138		// AMD. Register as an anonymous module.
90139		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(2), __webpack_require__(5) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
90140				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
90141				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
90142				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
90143	} else {
90144
90145		// Browser globals
90146		factory( jQuery );
90147	}
90148} )( function( $ ) {
90149"use strict";
90150
90151return $.fn.scrollParent = function( includeHidden ) {
90152	var position = this.css( "position" ),
90153		excludeStaticParent = position === "absolute",
90154		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
90155		scrollParent = this.parents().filter( function() {
90156			var parent = $( this );
90157			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
90158				return false;
90159			}
90160			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
90161				parent.css( "overflow-x" ) );
90162		} ).eq( 0 );
90163
90164	return position === "fixed" || !scrollParent.length ?
90165		$( this[ 0 ].ownerDocument || document ) :
90166		scrollParent;
90167};
90168
90169} );
90170
90171
90172/***/ }),
90173/* 273 */
90174/***/ (function(module, __webpack_exports__, __webpack_require__) {
90175
90176"use strict";
90177/* WEBPACK VAR INJECTION */(function($) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_swiper_bundle__ = __webpack_require__(6);
90178
90179
90180/* harmony default export */ __webpack_exports__["a"] = ({
90181  init: function init() {
90182    // JavaScript to be fired on all pages
90183  },
90184  finalize: function finalize() {
90185
90186    /**
90187     * Swiper Cards
90188     */
90189    if ( $('.cards_tour__list__slider').length > 0 ) {
90190      console.log('slider');
90191      var swiperCards = {};
90192      $('.cards_tour__list__slider').each(function (index) {
90193        var $this = $(this);
90194        $this.addClass('swiperCards-' + index);
90195
90196        swiperCards[index] =  new __WEBPACK_IMPORTED_MODULE_0_swiper_bundle__["a" /* default */]('.swiperCards-' + index + ' .swiper-container', {
90197          autoHeight: true, //enable auto height
90198          slidesPerView         : 'auto',
90199          spaceBetween          : 12,
90200          slidesOffsetBefore    : 44,
90201          loop                  : false,
90202          speed                 : 500,
90203          observer              : true,
90204          observeParents        : true,
90205          observeSlideChildren  : true,
90206          pagination: {
90207            el          : '.swiperCards-' + index + ' .swiper-pagination',
90208            clickable   : true,
90209            type        : 'bullets',
90210          },
90211          navigation: {
90212            nextEl      : '.swiperCards-' + index + ' .swiper-button-next',
90213            prevEl      : '.swiperCards-' + index + ' .swiper-button-prev',
90214          },
90215        });
90216
90217      });
90218
90219
90220
90221
90222
90223    }
90224
90225    /**
90226     * To Scroll
90227     * @click
90228     */
90229    $('.intro_tour__scroll').on('click', function (event) {
90230      event.preventDefault();
90231
90232      var id  = $(this).attr('href'),
90233          header = $('.header_tour__inner').height(),
90234          top = parseInt($(id).offset().top - header);
90235
90236      $('body,html').animate({scrollTop: top}, 900);
90237    });
90238
90239
90240  },
90241});
90242
90243/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(2)))
90244
90245/***/ }),
90246/* 274 */
90247/***/ (function(module, exports, __webpack_require__) {
90248
90249/* WEBPACK VAR INJECTION */(function(jQuery) {/* eslint no-prototype-builtins: 0 */
90250/* eslint-disable */
90251/**
90252 * jQuery-csv (jQuery Plugin)
90253 *
90254 * This document is licensed as free software under the terms of the
90255 * MIT License: http://www.opensource.org/licenses/mit-license.php
90256 *
90257 * Acknowledgements:
90258 * The original design and influence to implement this library as a jquery
90259 * plugin is influenced by jquery-json (http://code.google.com/p/jquery-json/).
90260 * If you're looking to use native JSON.Stringify but want additional backwards
90261 * compatibility for browsers that don't support it, I highly recommend you
90262 * check it out.
90263 *
90264 * A special thanks goes out to [email protected] for providing a lot of valuable
90265 * feedback to the project including the core for the new FSM
90266 * (Finite State Machine) parsers. If you're looking for a stable TSV parser
90267 * be sure to take a look at jquery-tsv (http://code.google.com/p/jquery-tsv/).
90268
90269 * For legal purposes I'll include the "NO WARRANTY EXPRESSED OR IMPLIED.
90270 * USE AT YOUR OWN RISK.". Which, in 'layman's terms' means, by using this
90271 * library you are accepting responsibility if it breaks your code.
90272 *
90273 * Legal jargon aside, I will do my best to provide a useful and stable core
90274 * that can effectively be built on.
90275 *
90276 * Copyrighted 2012 by Evan Plaice.
90277 */
90278
90279RegExp.escape = function (s) {
90280  return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
90281};
90282
90283(function () {
90284  'use strict'
90285
90286  var $
90287
90288  // to keep backwards compatibility
90289  if (typeof jQuery !== 'undefined' && jQuery) {
90290    $ = jQuery
90291  } else {
90292    $ = {}
90293  }
90294
90295  /**
90296   * jQuery.csv.defaults
90297   * Encapsulates the method paramater defaults for the CSV plugin module.
90298   */
90299
90300  $.csv = {
90301    defaults: {
90302      separator: ',',
90303      delimiter: '"',
90304      headers: true
90305    },
90306
90307    hooks: {
90308      castToScalar: function (value, state) {
90309        var hasDot = /\./
90310        if (isNaN(value)) {
90311          return value
90312        } else {
90313          if (hasDot.test(value)) {
90314            return parseFloat(value)
90315          } else {
90316            var integer = parseInt(value)
90317            if (isNaN(integer)) {
90318              return null
90319            } else {
90320              return integer
90321            }
90322          }
90323        }
90324      }
90325    },
90326
90327    parsers: {
90328      parse: function (csv, options) {
90329        // cache settings
90330        var separator = options.separator
90331        var delimiter = options.delimiter
90332
90333        // set initial state if it's missing
90334        if (!options.state.rowNum) {
90335          options.state.rowNum = 1
90336        }
90337        if (!options.state.colNum) {
90338          options.state.colNum = 1
90339        }
90340
90341        // clear initial state
90342        var data = []
90343        var entry = []
90344        var state = 0
90345        var value = ''
90346        var exit = false
90347
90348        function endOfEntry () {
90349          // reset the state
90350          state = 0
90351          value = ''
90352
90353          // if 'start' hasn't been met, don't output
90354          if (options.start && options.state.rowNum < options.start) {
90355            // update global state
90356            entry = []
90357            options.state.rowNum++
90358            options.state.colNum = 1
90359            return
90360          }
90361
90362          if (options.onParseEntry === undefined) {
90363            // onParseEntry hook not set
90364            data.push(entry)
90365          } else {
90366            var hookVal = options.onParseEntry(entry, options.state) // onParseEntry Hook
90367            // false skips the row, configurable through a hook
90368            if (hookVal !== false) {
90369              data.push(hookVal)
90370            }
90371          }
90372          // console.log('entry:' + entry);
90373
90374          // cleanup
90375          entry = []
90376
90377          // if 'end' is met, stop parsing
90378          if (options.end && options.state.rowNum >= options.end) {
90379            exit = true
90380          }
90381
90382          // update global state
90383          options.state.rowNum++
90384          options.state.colNum = 1
90385        }
90386
90387        function endOfValue () {
90388          if (options.onParseValue === undefined) {
90389            // onParseValue hook not set
90390            entry.push(value)
90391          } else if (options.headers && options.state.rowNum === 1) {
90392            // don't onParseValue object headers
90393            entry.push(value)
90394          } else {
90395            var hook = options.onParseValue(value, options.state) // onParseValue Hook
90396            // false skips the row, configurable through a hook
90397            if (hook !== false) {
90398              entry.push(hook)
90399            }
90400          }
90401          // console.log('value:' + value);
90402          // reset the state
90403          value = ''
90404          state = 0
90405          // update global state
90406          options.state.colNum++
90407        }
90408
90409        // escape regex-specific control chars
90410        var escSeparator = RegExp.escape(separator)
90411        var escDelimiter = RegExp.escape(delimiter)
90412
90413        // compile the regEx str using the custom delimiter/separator
90414        var match = /(D|S|\r\n|\n|\r|[^DS\r\n]+)/
90415        var matchSrc = match.source
90416        matchSrc = matchSrc.replace(/S/g, escSeparator)
90417        matchSrc = matchSrc.replace(/D/g, escDelimiter)
90418        match = new RegExp(matchSrc, 'gm')
90419
90420        // put on your fancy pants...
90421        // process control chars individually, use look-ahead on non-control chars
90422        csv.replace(match, function (m0) {
90423          if (exit) {
90424            return
90425          }
90426          switch (state) {
90427            // the start of a value
90428            case 0:
90429              // null last value
90430              if (m0 === separator) {
90431                value += ''
90432                endOfValue()
90433                break
90434              }
90435              // opening delimiter
90436              if (m0 === delimiter) {
90437                state = 1
90438                break
90439              }
90440              // null last value
90441              if (/^(\r\n|\n|\r)$/.test(m0)) {
90442                endOfValue()
90443                endOfEntry()
90444                break
90445              }
90446              // un-delimited value
90447              value += m0
90448              state = 3
90449              break
90450
90451            // delimited input
90452            case 1:
90453              // second delimiter? check further
90454              if (m0 === delimiter) {
90455                state = 2
90456                break
90457              }
90458              // delimited data
90459              value += m0
90460              state = 1
90461              break
90462
90463            // delimiter found in delimited input
90464            case 2:
90465              // escaped delimiter?
90466              if (m0 === delimiter) {
90467                value += m0
90468                state = 1
90469                break
90470              }
90471              // null value
90472              if (m0 === separator) {
90473                endOfValue()
90474                break
90475              }
90476              // end of entry
90477              if (/^(\r\n|\n|\r)$/.test(m0)) {
90478                endOfValue()
90479                endOfEntry()
90480                break
90481              }
90482              // broken paser?
90483              throw Error('CSVDataError: Illegal State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']')
90484
90485            // un-delimited input
90486            case 3:
90487              // null last value
90488              if (m0 === separator) {
90489                endOfValue()
90490                break
90491              }
90492              // end of entry
90493              if (/^(\r\n|\n|\r)$/.test(m0)) {
90494                endOfValue()
90495                endOfEntry()
90496                break
90497              }
90498              if (m0 === delimiter) {
90499              // non-compliant data
90500                throw Error('CSVDataError: Illegal Quote [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']')
90501              }
90502              // broken parser?
90503              throw Error('CSVDataError: Illegal Data [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']')
90504            default:
90505              // shenanigans
90506              throw Error('CSVDataError: Unknown State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']')
90507          }
90508          // console.log('val:' + m0 + ' state:' + state);
90509        })
90510
90511        // submit the last entry
90512        // ignore null last line
90513        if (entry.length !== 0) {
90514          endOfValue()
90515          endOfEntry()
90516        }
90517
90518        return data
90519      },
90520
90521      // a csv-specific line splitter
90522      splitLines: function (csv, options) {
90523        if (!csv) {
90524          return undefined
90525        }
90526
90527        options = options || {}
90528
90529        // cache settings
90530        var separator = options.separator || $.csv.defaults.separator
90531        var delimiter = options.delimiter || $.csv.defaults.delimiter
90532
90533        // set initial state if it's missing
90534        options.state = options.state || {}
90535        if (!options.state.rowNum) {
90536          options.state.rowNum = 1
90537        }
90538
90539        // clear initial state
90540        var entries = []
90541        var state = 0
90542        var entry = ''
90543        var exit = false
90544
90545        function endOfLine () {
90546          // reset the state
90547          state = 0
90548
90549          // if 'start' hasn't been met, don't output
90550          if (options.start && options.state.rowNum < options.start) {
90551            // update global state
90552            entry = ''
90553            options.state.rowNum++
90554            return
90555          }
90556
90557          if (options.onParseEntry === undefined) {
90558            // onParseEntry hook not set
90559            entries.push(entry)
90560          } else {
90561            var hookVal = options.onParseEntry(entry, options.state) // onParseEntry Hook
90562            // false skips the row, configurable through a hook
90563            if (hookVal !== false) {
90564              entries.push(hookVal)
90565            }
90566          }
90567
90568          // cleanup
90569          entry = ''
90570
90571          // if 'end' is met, stop parsing
90572          if (options.end && options.state.rowNum >= options.end) {
90573            exit = true
90574          }
90575
90576          // update global state
90577          options.state.rowNum++
90578        }
90579
90580        // escape regex-specific control chars
90581        var escSeparator = RegExp.escape(separator)
90582        var escDelimiter = RegExp.escape(delimiter)
90583
90584        // compile the regEx str using the custom delimiter/separator
90585        var match = /(D|S|\n|\r|[^DS\r\n]+)/
90586        var matchSrc = match.source
90587        matchSrc = matchSrc.replace(/S/g, escSeparator)
90588        matchSrc = matchSrc.replace(/D/g, escDelimiter)
90589        match = new RegExp(matchSrc, 'gm')
90590
90591        // put on your fancy pants...
90592        // process control chars individually, use look-ahead on non-control chars
90593        csv.replace(match, function (m0) {
90594          if (exit) {
90595            return
90596          }
90597          switch (state) {
90598            // the start of a value/entry
90599            case 0:
90600              // null value
90601              if (m0 === separator) {
90602                entry += m0
90603                state = 0
90604                break
90605              }
90606              // opening delimiter
90607              if (m0 === delimiter) {
90608                entry += m0
90609                state = 1
90610                break
90611              }
90612              // end of line
90613              if (m0 === '\n') {
90614                endOfLine()
90615                break
90616              }
90617              // phantom carriage return
90618              if (/^\r$/.test(m0)) {
90619                break
90620              }
90621              // un-delimit value
90622              entry += m0
90623              state = 3
90624              break
90625
90626            // delimited input
90627            case 1:
90628              // second delimiter? check further
90629              if (m0 === delimiter) {
90630                entry += m0
90631                state = 2
90632                break
90633              }
90634              // delimited data
90635              entry += m0
90636              state = 1
90637              break
90638
90639            // delimiter found in delimited input
90640            case 2: {
90641              // escaped delimiter?
90642              var prevChar = entry.substr(entry.length - 1)
90643              if (m0 === delimiter && prevChar === delimiter) {
90644                entry += m0
90645                state = 1
90646                break
90647              }
90648              // end of value
90649              if (m0 === separator) {
90650                entry += m0
90651                state = 0
90652                break
90653              }
90654              // end of line
90655              if (m0 === '\n') {
90656                endOfLine()
90657                break
90658              }
90659              // phantom carriage return
90660              if (m0 === '\r') {
90661                break
90662              }
90663              // broken paser?
90664              throw Error('CSVDataError: Illegal state [Row:' + options.state.rowNum + ']')
90665            }
90666            // un-delimited input
90667            case 3:
90668              // null value
90669              if (m0 === separator) {
90670                entry += m0
90671                state = 0
90672                break
90673              }
90674              // end of line
90675              if (m0 === '\n') {
90676                endOfLine()
90677                break
90678              }
90679              // phantom carriage return
90680              if (m0 === '\r') {
90681                break
90682              }
90683              // non-compliant data
90684              if (m0 === delimiter) {
90685                throw Error('CSVDataError: Illegal quote [Row:' + options.state.rowNum + ']')
90686              }
90687              // broken parser?
90688              throw Error('CSVDataError: Illegal state [Row:' + options.state.rowNum + ']')
90689            default:
90690              // shenanigans
90691              throw Error('CSVDataError: Unknown state [Row:' + options.state.rowNum + ']')
90692          }
90693          // console.log('val:' + m0 + ' state:' + state);
90694        })
90695
90696        // submit the last entry
90697        // ignore null last line
90698        if (entry !== '') {
90699          endOfLine()
90700        }
90701
90702        return entries
90703      },
90704
90705      // a csv entry parser
90706      parseEntry: function (csv, options) {
90707        // cache settings
90708        var separator = options.separator
90709        var delimiter = options.delimiter
90710
90711        // set initial state if it's missing
90712        if (!options.state.rowNum) {
90713          options.state.rowNum = 1
90714        }
90715        if (!options.state.colNum) {
90716          options.state.colNum = 1
90717        }
90718
90719        // clear initial state
90720        var entry = []
90721        var state = 0
90722        var value = ''
90723
90724        function endOfValue () {
90725          if (options.onParseValue === undefined) {
90726            // onParseValue hook not set
90727            entry.push(value)
90728          } else {
90729            var hook = options.onParseValue(value, options.state) // onParseValue Hook
90730            // false skips the value, configurable through a hook
90731            if (hook !== false) {
90732              entry.push(hook)
90733            }
90734          }
90735          // reset the state
90736          value = ''
90737          state = 0
90738          // update global state
90739          options.state.colNum++
90740        }
90741
90742        // checked for a cached regEx first
90743        if (!options.match) {
90744          // escape regex-specific control chars
90745          var escSeparator = RegExp.escape(separator)
90746          var escDelimiter = RegExp.escape(delimiter)
90747
90748          // compile the regEx str using the custom delimiter/separator
90749          var match = /(D|S|\n|\r|[^DS\r\n]+)/
90750          var matchSrc = match.source
90751          matchSrc = matchSrc.replace(/S/g, escSeparator)
90752          matchSrc = matchSrc.replace(/D/g, escDelimiter)
90753          options.match = new RegExp(matchSrc, 'gm')
90754        }
90755
90756        // put on your fancy pants...
90757        // process control chars individually, use look-ahead on non-control chars
90758        csv.replace(options.match, function (m0) {
90759          switch (state) {
90760            // the start of a value
90761            case 0:
90762              // null last value
90763              if (m0 === separator) {
90764                value += ''
90765                endOfValue()
90766                break
90767              }
90768              // opening delimiter
90769              if (m0 === delimiter) {
90770                state = 1
90771                break
90772              }
90773              // skip un-delimited new-lines
90774              if (m0 === '\n' || m0 === '\r') {
90775                break
90776              }
90777              // un-delimited value
90778              value += m0
90779              state = 3
90780              break
90781
90782            // delimited input
90783            case 1:
90784              // second delimiter? check further
90785              if (m0 === delimiter) {
90786                state = 2
90787                break
90788              }
90789              // delimited data
90790              value += m0
90791              state = 1
90792              break
90793
90794            // delimiter found in delimited input
90795            case 2:
90796              // escaped delimiter?
90797              if (m0 === delimiter) {
90798                value += m0
90799                state = 1
90800                break
90801              }
90802              // null value
90803              if (m0 === separator) {
90804                endOfValue()
90805                break
90806              }
90807              // skip un-delimited new-lines
90808              if (m0 === '\n' || m0 === '\r') {
90809                break
90810              }
90811              // broken paser?
90812              throw Error('CSVDataError: Illegal State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']')
90813
90814            // un-delimited input
90815            case 3:
90816              // null last value
90817              if (m0 === separator) {
90818                endOfValue()
90819                break
90820              }
90821              // skip un-delimited new-lines
90822              if (m0 === '\n' || m0 === '\r') {
90823                break
90824              }
90825              // non-compliant data
90826              if (m0 === delimiter) {
90827                throw Error('CSVDataError: Illegal Quote [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']')
90828              }
90829              // broken parser?
90830              throw Error('CSVDataError: Illegal Data [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']')
90831            default:
90832              // shenanigans
90833              throw Error('CSVDataError: Unknown State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']')
90834          }
90835          // console.log('val:' + m0 + ' state:' + state);
90836        })
90837
90838        // submit the last value
90839        endOfValue()
90840
90841        return entry
90842      }
90843    },
90844
90845    helpers: {
90846
90847      /**
90848       * $.csv.helpers.collectPropertyNames(objectsArray)
90849       * Collects all unique property names from all passed objects.
90850       *
90851       * @param {Array} objects Objects to collect properties from.
90852       *
90853       * Returns an array of property names (array will be empty,
90854       * if objects have no own properties).
90855       */
90856      collectPropertyNames: function (objects) {
90857        var o = []
90858        var propName = []
90859        var props = []
90860        for (o in objects) {
90861          for (propName in objects[o]) {
90862            if ((objects[o].hasOwnProperty(propName)) &&
90863                (props.indexOf(propName) < 0) &&
90864                (typeof objects[o][propName] !== 'function')) {
90865              props.push(propName)
90866            }
90867          }
90868        }
90869        return props
90870      }
90871    },
90872
90873    /**
90874     * $.csv.toArray(csv)
90875     * Converts a CSV entry string to a javascript array.
90876     *
90877     * @param {Array} csv The string containing the CSV data.
90878     * @param {Object}
90878 [options] An object containing user-defined options.
90879     * @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
90880     * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
90881     *
90882     * This method deals with simple CSV strings only. It's useful if you only
90883     * need to parse a single entry. If you need to parse more than one line,
90884     * use $.csv2Array instead.
90885     */
90886    toArray: function (csv, options, callback) {
90887      // if callback was passed to options swap callback with options
90888      if (options !== undefined && typeof (options) === 'function') {
90889        if (callback !== undefined) {
90890          return console.error('You cannot 3 arguments with the 2nd argument being a function')
90891        }
90892        callback = options
90893        options = {}
90894      }
90895
90896      options = (options !== undefined ? options : {})
90897      var config = {}
90898      config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false)
90899      config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator
90900      config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter
90901      var state = (options.state !== undefined ? options.state : {})
90902
90903      // setup
90904      options = {
90905        delimiter: config.delimiter,
90906        separator: config.separator,
90907        onParseEntry: options.onParseEntry,
90908        onParseValue: options.onParseValue,
90909        state: state
90910      }
90911
90912      var entry = $.csv.parsers.parseEntry(csv, options)
90913
90914      // push the value to a callback if one is defined
90915      if (!config.callback) {
90916        return entry
90917      } else {
90918        config.callback('', entry)
90919      }
90920    },
90921
90922    /**
90923     * $.csv.toArrays(csv)
90924     * Converts a CSV string to a javascript array.
90925     *
90926     * @param {String} csv The string containing the raw CSV data.
90927     * @param {Object} [options] An object containing user-defined options.
90928     * @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
90929     * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
90930     *
90931     * This method deals with multi-line CSV. The breakdown is simple. The first
90932     * dimension of the array represents the line (or entry/row) while the second
90933     * dimension contains the values (or values/columns).
90934     */
90935    toArrays: function (csv, options, callback) {
90936      // if callback was passed to options swap callback with options
90937      if (options !== undefined && typeof (options) === 'function') {
90938        if (callback !== undefined) {
90939          return console.error('You cannot 3 arguments with the 2nd argument being a function')
90940        }
90941        callback = options
90942        options = {}
90943      }
90944
90945      options = (options !== undefined ? options : {})
90946      var config = {}
90947      config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false)
90948      config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator
90949      config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter
90950
90951      // setup
90952      var data = []
90953      options = {
90954        delimiter: config.delimiter,
90955        separator: config.separator,
90956        onPreParse: options.onPreParse,
90957        onParseEntry: options.onParseEntry,
90958        onParseValue: options.onParseValue,
90959        onPostParse: options.onPostParse,
90960        start: options.start,
90961        end: options.end,
90962        state: {
90963          rowNum: 1,
90964          colNum: 1
90965        }
90966      }
90967
90968      // onPreParse hook
90969      if (options.onPreParse !== undefined) {
90970        csv = options.onPreParse(csv, options.state)
90971      }
90972
90973      // parse the data
90974      data = $.csv.parsers.parse(csv, options)
90975
90976      // onPostParse hook
90977      if (options.onPostParse !== undefined) {
90978        data = options.onPostParse(data, options.state)
90979      }
90980
90981      // push the value to a callback if one is defined
90982      if (!config.callback) {
90983        return data
90984      } else {
90985        config.callback('', data)
90986      }
90987    },
90988
90989    /**
90990     * $.csv.toObjects(csv)
90991     * Converts a CSV string to a javascript object.
90992     * @param {String} csv The string containing the raw CSV data.
90993     * @param {Object}
90993 [options] An object containing user-defined options.
90994     * @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
90995     * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
90996     * @param {Boolean} [headers] Indicates whether the data contains a header line. Defaults to true.
90997     *
90998     * This method deals with multi-line CSV strings. Where the headers line is
90999     * used as the key for each value per entry.
91000     */
91001    toObjects: function (csv, options, callback) {
91002      // if callback was passed to options swap callback with options
91003      if (options !== undefined && typeof (options) === 'function') {
91004        if (callback !== undefined) {
91005          return console.error('You cannot 3 arguments with the 2nd argument being a function')
91006        }
91007        callback = options
91008        options = {}
91009      }
91010
91011      options = (options !== undefined ? options : {})
91012      var config = {}
91013      config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false)
91014      config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator
91015      config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter
91016      config.headers = 'headers' in options ? options.headers : $.csv.defaults.headers
91017      options.start = 'start' in options ? options.start : 1
91018
91019      // account for headers
91020      if (config.headers) {
91021        options.start++
91022      }
91023      if (options.end && config.headers) {
91024        options.end++
91025      }
91026
91027      // setup
91028      var lines = []
91029      var data = []
91030
91031      options = {
91032        delimiter: config.delimiter,
91033        separator: config.separator,
91034        onPreParse: options.onPreParse,
91035        onParseEntry: options.onParseEntry,
91036        onParseValue: options.onParseValue,
91037        onPostParse: options.onPostParse,
91038        start: options.start,
91039        end: options.end,
91040        state: {
91041          rowNum: 1,
91042          colNum: 1
91043        },
91044        match: false,
91045        transform: options.transform
91046      }
91047
91048      // fetch the headers
91049      var headerOptions = {
91050        delimiter: config.delimiter,
91051        separator: config.separator,
91052        start: 1,
91053        end: 1,
91054        state: {
91055          rowNum: 1,
91056          colNum: 1
91057        },
91058        headers: true
91059      }
91060
91061      // onPreParse hook
91062      if (options.onPreParse !== undefined) {
91063        csv = options.onPreParse(csv, options.state)
91064      }
91065
91066      // parse the csv
91067      var headerLine = $.csv.parsers.splitLines(csv, headerOptions)
91068      var headers = $.csv.toArray(headerLine[0], headerOptions)
91069
91070      // fetch the data
91071      lines = $.csv.parsers.splitLines(csv, options)
91072
91073      // reset the state for re-use
91074      options.state.colNum = 1
91075      if (headers) {
91076        options.state.rowNum = 2
91077      } else {
91078        options.state.rowNum = 1
91079      }
91080
91081      // convert data to objects
91082      for (var i = 0, len = lines.length; i < len; i++) {
91083        var entry = $.csv.toArray(lines[i], options)
91084        var object = {}
91085        for (var j = 0; j < headers.length; j++) {
91086          object[headers[j]] = entry[j]
91087        }
91088        if (options.transform !== undefined) {
91089          data.push(options.transform.call(undefined, object))
91090        } else {
91091          data.push(object)
91092        }
91093
91094        // update row state
91095        options.state.rowNum++
91096      }
91097
91098      // onPostParse hook
91099      if (options.onPostParse !== undefined) {
91100        data = options.onPostParse(data, options.state)
91101      }
91102
91103      // push the value to a callback if one is defined
91104      if (!config.callback) {
91105        return data
91106      } else {
91107        config.callback('', data)
91108      }
91109    },
91110
91111    /**
91112    * $.csv.fromArrays(arrays)
91113    * Converts a javascript array to a CSV String.
91114    *
91115    * @param {Array} arrays An array containing an array of CSV entries.
91116    * @param {Object} [options] An object containing user-defined options.
91117    * @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
91118    * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
91119    *
91120    * This method generates a CSV file from an array of arrays (representing entries).
91121    */
91122    fromArrays: function (arrays, options, callback) {
91123      // if callback was passed to options swap callback with options
91124      if (options !== undefined && typeof (options) === 'function') {
91125        if (callback !== undefined) {
91126          return console.error('You cannot 3 arguments with the 2nd argument being a function')
91127        }
91128        callback = options
91129        options = {}
91130      }
91131
91132      options = (options !== undefined ? options : {})
91133      var config = {}
91134      config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false)
91135      config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator
91136      config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter
91137
91138      var output = ''
91139
91140      for (var i = 0; i < arrays.length; i++) {
91141        var line = arrays[i]
91142        var lineValues = []
91143        for (var j = 0; j < line.length; j++) {
91144          var strValue = (line[j] === undefined || line[j] === null) ? '' : line[j].toString()
91145          if (strValue.indexOf(config.delimiter) > -1) {
91146            strValue = strValue.replace(new RegExp(config.delimiter, 'g'), config.delimiter + config.delimiter)
91147          }
91148
91149          var escMatcher = '\n|\r|S|D'
91150          escMatcher = escMatcher.replace('S', config.separator)
91151          escMatcher = escMatcher.replace('D', config.delimiter)
91152
91153          if (strValue.search(escMatcher) > -1) {
91154            strValue = config.delimiter + strValue + config.delimiter
91155          }
91156          lineValues.push(strValue)
91157        }
91158        output += lineValues.join(config.separator) + '\n'
91159      }
91160
91161      // push the value to a callback if one is defined
91162      if (!config.callback) {
91163        return output
91164      } else {
91165        config.callback('', output)
91166      }
91167    },
91168
91169    /**
91170     * $.csv.fromObjects(objects)
91171     * Converts a javascript dictionary to a CSV string.
91172     *
91173     * @param {Object} objects An array of objects containing the data.
91174     * @param {Object} [options] An object containing user-defined options.
91175     * @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
91176     * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
91177     * @param {Character} [sortOrder] Sort order of columns (named after
91178     *   object properties). Use 'alpha' for alphabetic. Default is 'declare',
91179     *   which means, that properties will _probably_ appear in order they were
91180     *   declared for the object. But without any guarantee.
91181     * @param {Character or Array} [manualOrder] Manually order columns. May be
91182     * a strin in a same csv format as an output or an array of header names
91183     * (array items won't be parsed). All the properties, not present in
91184     * `manualOrder` will be appended to the end in accordance with `sortOrder`
91185     * option. So the `manualOrder` always takes preference, if present.
91186     *
91187     * This method generates a CSV file from an array of objects (name:value pairs).
91188     * It starts by detecting the headers and adding them as the first line of
91189     * the CSV file, followed by a structured dump of the data.
91190     */
91191    fromObjects: function (objects, options, callback) {
91192      // if callback was passed to options swap callback with options
91193      if (options !== undefined && typeof (options) === 'function') {
91194        if (callback !== undefined) {
91195          return console.error('You cannot 3 arguments with the 2nd argument being a function')
91196        }
91197        callback = options
91198        options = {}
91199      }
91200
91201      options = (options !== undefined ? options : {})
91202      var config = {}
91203      config.callback = ((callback !== undefined && typeof (callback) === 'function') ? callback : false)
91204      config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator
91205      config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter
91206      config.headers = 'headers' in options ? options.headers : $.csv.defaults.headers
91207      config.sortOrder = 'sortOrder' in options ? options.sortOrder : 'declare'
91208      config.manualOrder = 'manualOrder' in options ? options.manualOrder : []
91209      config.transform = options.transform
91210
91211      if (typeof config.manualOrder === 'string') {
91212        config.manualOrder = $.csv.toArray(config.manualOrder, config)
91213      }
91214
91215      if (config.transform !== undefined) {
91216        var origObjects = objects
91217        objects = []
91218
91219        for (var i = 0; i < origObjects.length; i++) {
91220          objects.push(config.transform.call(undefined, origObjects[i]))
91221        }
91222      }
91223
91224      var props = $.csv.helpers.collectPropertyNames(objects)
91225
91226      if (config.sortOrder === 'alpha') {
91227        props.sort()
91228      }
91229
91230      if (config.manualOrder.length > 0) {
91231        var propsManual = [].concat(config.manualOrder)
91232
91233        for (var p = 0; p < props.length; p++) {
91234          if (propsManual.indexOf(props[p]) < 0) {
91235            propsManual.push(props[p])
91236          }
91237        }
91238        props = propsManual
91239      }
91240
91241      var line
91242      var output = []
91243      var propName
91244      if (config.headers) {
91245        output.push(props)
91246      }
91247
91248      for (var o = 0; o < objects.length; o++) {
91249        line = []
91250        for (var p$1 = 0; p$1 < props.length; p$1++) {
91251          propName = props[p$1]
91252          if (propName in objects[o] && typeof objects[o][propName] !== 'function') {
91253            line.push(objects[o][propName])
91254          } else {
91255            line.push('')
91256          }
91257        }
91258        output.push(line)
91259      }
91260
91261      // push the value to a callback if one is defined
91262      return $.csv.fromArrays(output, options, config.callback)
91263    }
91264  }
91265
91266  // Maintenance code to maintain backward-compatibility
91267  // Will be removed in release 1.0
91268  $.csvEntry2Array = $.csv.toArray
91269  $.csv2Array = $.csv.toArrays
91270  $.csv2Dictionary = $.csv.toObjects
91271
91272  // CommonJS module is defined
91273  if (typeof module !== 'undefined' && module.exports) {
91274    module.exports = $.csv
91275  }
91276}).call(this)
91277
91278/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2)))
91279
91280/***/ }),
91281/* 275 */
91282/***/ (function(module, exports) {
91283
91284// removed by extract-text-webpack-plugin
91285
91286/***/ })
91287/******/ ]);
91288//# sourceMappingURL=main.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.