PageSourceSearch

https://cdn1.img.sputniknews.jp/min/js/dist/footer.js?966fca839

js sputniknews.jp collected 2026-10-02 06:57:39 UTC 810,328 bytes, 16,711 lines download raw bytes

1$(function () {
2	/* создание отложенных действий */
3	if (GLOBAL) {
4		GLOBAL.events = {
5			subscriptions: {},
6			/* Обнуляет все подписки */
7			reset: function () {
8				GLOBAL.events.subscriptions = {}
9			},
10			/* Подписывает на событие */
11			subscribe: function (message, callback) {
12				if (typeof GLOBAL.events.subscriptions[message] === 'undefined') {
13					GLOBAL.events.subscriptions[message] = [];
14				}
15				GLOBAL.events.subscriptions[message].push(callback);
16			},
17			/* Выполняет событие */
18			trigger: function (message, params) {
19				if (typeof GLOBAL.events.subscriptions[message] === 'undefined') {
20					return;
21				}
22				var subscribers = GLOBAL.events.subscriptions[message];
23				for (key in subscribers) {
24					subscribers[key](params);
25				}
26			}
27		}
28	}
29});
30(function( w ){
31    var loadJS = function( src, cb, ordered ){
32        "use strict";
33        var tmp;
34        var ref = w.document.getElementsByTagName( "script" )[ 0 ];
35        var script = w.document.createElement( "script" );
36
37        if (typeof(cb) === 'boolean') {
38            tmp = ordered;
39            ordered = cb;
40            cb = tmp;
41        }
42
43        script.src = src;
44        script.async = !ordered;
45        ref.parentNode.insertBefore( script, ref );
46
47        if (cb && typeof(cb) === "function") {
48            script.onload = cb;
49        }
50        return script;
51    };
52    if( typeof module !== "undefined" ){
53        module.exports = loadJS;
54    }
55    else {
56        w.loadJS = loadJS;
57    }
58}( typeof global !== "undefined" ? global : this ));
59
60(function( w ){
61	var loadCSS = function( href ){
62		"use strict";
63		if (!document.querySelectorAll('link[href="' + href +'"]').length) {
64			var head  = document.getElementsByTagName('head')[0];
65			var link  = document.createElement('link');
66			link.rel  = 'stylesheet';
67			link.type = 'text/css';
68			link.href = href;
69			link.media = 'all';
70			head.appendChild(link);
71		}
72	};
73	w.loadCSS = loadCSS;
74}( typeof global !== "undefined" ? global : this ));
75
76// PolyFill for "isIntersecting"
77// https://github.com/w3c/IntersectionObserver/issues/211#issuecomment-309144669
78if ('IntersectionObserver' in window &&
79    'IntersectionObserverEntry' in window &&
80    'intersectionRatio' in window.IntersectionObserverEntry.prototype &&
81    !('isIntersecting' in IntersectionObserverEntry.prototype)) {
82
83    Object.defineProperty(window.IntersectionObserverEntry.prototype, 'isIntersecting', {
84        get: function () {
85            return this.intersectionRatio > 0
86        }
87    })
88}
89
90
91function lazyload() {
92    var lazyImages = [].slice.call(document.querySelectorAll(".lazyload"));
93
94    if ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype) {
95        var lazyImageObserver = new IntersectionObserver(function(entries, observer) {
96            entries.forEach(function(entry) {
97                if (entry.isIntersecting) {
98                    var lazyImage = entry.target;
99                    lazyloadImage(lazyImage);
100                    lazyImage.classList.remove("lazyload");
101                    lazyImageObserver.unobserve(lazyImage);
102                }
103            });
104        }, {
105            rootMargin: "100px"
106        });
107
108        lazyImages.forEach(function(lazyImage) {
109            lazyImageObserver.observe(lazyImage);
110        });
111    } else {
112        setTimeout(function() {
113            lazyImages.forEach(function(lazyImage) {
114                lazyloadImage(lazyImage)
115            });
116        }, 1000)
117    }
118}
119
120function lazyloadImage(image) {
121    if (image.dataset && image.dataset.srcset) {
122        image.srcset = image.dataset.srcset;
123    }
124
125    if (image.dataset && image.dataset.src) {
126        // setTimeout(function() {
127            image.src = image.dataset.src;
128        // }, 500)
129    }
130}
131
132function lazyloadScript(selectors, callback) {
133    if ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype) {
134        var scriptObserver = new IntersectionObserver(function(entries, observer) {
135            entries.forEach(function(entry) {
136                if (entry.isIntersecting) {
137                    callback.apply();
138                    scriptObserver.disconnect();
139                }
140            });
141        });
142        var els = [].slice.call(document.querySelectorAll(selectors));
143        els.forEach(function(el) {
144            scriptObserver.observe(el);
145        });
146    } else {
147        callback.apply();
148    }
149}
150
151
152// PolyFill for nodelist.foreach()
153// https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#Polyfill
154// if (window.NodeList && !NodeList.prototype.forEach) {
155//     NodeList.prototype.forEach = function (callback, thisArg) {
156//         thisArg = thisArg || window;
157//         for (var i = 0; i < this.length; i++) {
158//             callback.call(thisArg, this[i], i, this);
159//         }
160//     };
161// }
162
163
164/**
165 *  version 2.0
166 *
167 *
168 *  ==============================================================
169 *  Triggers
170 *  ==============================================================
171 *
172 *  initialized.the-in-scroll
173 *  refresh.the-in-scroll
174 *  refreshed.the-in-scroll
175 *  up-pos.the-in-scroll
176 *  down-pos.the-in-scroll
177 *
178 *  пример:
179 *  $('.the-in-scroll').on( 'up-pos.the-in-scroll', function( event, data ){ ... })
180
181 *  data = {
182 *      eventType   : "up-pos"
183 *      plugin      : plugin element
184 *      scroliing   : 50                    - позиция строла в %
185 *      scroller    : {
186 *          position : {
187 *              pc : 34,                    - позиция кастомного строллера в %
188 *              px : 40,                    - позиция кастомного строллера в px
189 *          }
190 *          size : {
191 *              pc : 34,                    - размер кастомного строллера в %
192 *              px : 40,                    - размер кастомного строллера в px
193 *          }
194 *      }
195 *      content   : {
196 *          position : {
197 *              pc : 34,                    - позиция проскрола контента в %
198 *              px : 40,                    - позиция проскрола контента в px
199 *          }
200 *      }
201 *      scrollingline : {
202 *          size : {
203 *              px : 40,                    - размер кастомной полосы прокрутки в px
204 *          }
205 *      }
206 *  }
207 *
208 *
209 *  ==============================================================
210 *  Listener
211 *  ==============================================================
212 *
213 *  Скроллинг до нужной позиции
214 *
215 *  scroll-to.the-in-scroll                     - скроллинг до переданной позиции
216 *  @param { number | string }      position    - позиция для доскрола, принимает число, строку-число или строку со знаком "%" в конце - ОБЯЗАТЕЛЬНЫЙ параметр
217 *  @param { number  }              duration    - время анимации скролла, по умрочанию [ 500 ]
218 *
219 *  scroll-up.the-in-scroll                     - скроллинг в начало
220 *  @param { number | string }      position    - позиция для доскрола, принимает число, строку-число или строку со знаком "%" в конце - не обязательный параметр
221 *  @param { number  }              duration    - время анимации скролла, по умрочанию [ 500 ]
222 *
223 *  scroll-down.the-in-scroll                   - скроллинг в конец
224 *  @param { number | string }      position    - позиция для доскрола, принимает число, строку-число или строку со знаком "%" в конце - не обязательный параметр
225 *  @param { number  }              duration    - время анимации скролла, по умрочанию [ 500 ]
226 *
227 *  параметры: { number | string } [, { number } ]
228 *  примеры:
229 *  $('.the-in-scroll').trigger( 'scroll-to.the-in-scroll', [ 50 ] )         - px size
230 *  $('.the-in-scroll').trigger( 'scroll-up.the-in-scroll', [ 50, 100] )     - px size, duration animation
231 *  $('.the-in-scroll').trigger( 'scroll-down.the-in-scroll', [ '50%' ] )    - percent size
232 *  $('.the-in-scroll').trigger( 'scroll-to.the-in-scroll', [ '50%', 100 ] ) - percent size, duration animation
233 *
234 *  --------------------------------------------------------------
235 *  add-scrolling-trigger.the-in-scroll
236 *  --------------------------------------------------------------
237 *
238 *  Добавление тригера прокрутки больше или менбше позиции скрола
239 *
240 *  Принимает 2-7 параметров или объект с параметрами, обязательные первые 2 параметра ( name и position )
241 *
242 *  @param { string }           name        - принимает строку - название тригера
243 *  @param { number | string }  position    - позиция для срабатывания, принимает число, строку-число или строку со знаком "%" в конце
244 *  @param { '<', '>' }         sign        - знак для условия, по умолчанию [ ">" ]
245 *  @param { boolean }          down        - флаг - отсчет вести от низа, по умолчанию [ false ]
246 *  @param { boolean }          everytime   - флаг - срабатывать один раз за попадание в область, второй раз сработает после выхода из области, по умолчанию [ false ]
247 *  @param { boolean }          move        - флаг - тригер сработает только при изменении прокрутки, по умолчанию [ false ]
248 *  @param { boolean }          once        - флаг - тригер сработает один раз и будет удален, по умолчанию [ false ]
249 *
250 *  параметры:  { string }, { number | string } [, { '<', '>' }, { boolean }, { boolean }, { boolean }, { boolean } ]
251 *  примеры:
252 *  $('.the-in-scroll').trigger( 'add-scrolling-trigger.the-in-scroll', [ 'trigger-name', 100, );
253 *  $('.the-in-scroll').trigger( 'add-scrolling-trigger.the-in-scroll', [ 'trigger-name', 100, '<', true ] );
254 *  $('.the-in-scroll').trigger( 'add-scrolling-trigger.the-in-scroll', [ 'trigger-name', 100, '<', false, false, true ] );
255 *  $('.the-in-scroll').trigger( 'add-scrolling-trigger.the-in-scroll', [ 'trigger-name', 100, '<', false, false, false, true ] );
256 *
257 *  пример с объектом параметров :
258 *  $('.live.js__custom-scroll').trigger('add-scrolling-trigger.the-in-scroll', [ {
259 *      name: 'trigger-name',
260 *      position: 1,
261 *      sign: '<',
262 *      down: false,
263 *      everytime: true,
264 *      move: true,
265 *      once: false
266 *  } ]);
267 *
268 *  --------------------------------------------------------------
269 *  clear-content.the-in-scroll
270 *  --------------------------------------------------------------
271 *
272 *  Удаление контента
273 *
274 *  параметры: [ { boolean }, { number } ]                                      - нет обязательных параметров
275 *  примеры:
276 *  $('.the-in-scroll').trigger('clear-content.the-in-scroll')                  - просто удалит контент
277 *  $('.the-in-scroll').trigger('clear-content.the-in-scroll', [ true ] )       - удалит через slideUp со скоростью по умолчанию установленную в плагине [ 500 ]
278 *  $('.the-in-scroll').trigger('clear-content.the-in-scroll', [ true, 3000 ] ) - удалит через slideUp со скоростью 3000
279 *
280 *  --------------------------------------------------------------
281 *  add-content.the-in-scroll
282 *  --------------------------------------------------------------
283 *
284 *  Добавление контента
285 *
286 *  @param { object | string }   - принимает объект или строку обязательно состоящую из тега, которую сам преобразует в объект
287 *  @param { boolean }           - флаг добавить перед, принимает true или false
288 *  @param { boolean }           - добавить через slideDown со скоростью по умолчанию [500]
289 *  @param { number }            - скороcть для добавления через slideDown
290 *  параметры: { object | string } [ , { boolean }, { boolean }, { number } ]   - обязательным является только первый параметр
291 *
292 *  примеры:
293 *  $('.live').trigger('add-content.the-in-scroll', [ '<div>dasdasd</div>', true, true, 5000 ])
294 *  $('.live').trigger('add-content.the-in-scroll', [ $object, true, true, 5000 ])
295 *
296 *  --------------------------------------------------------------
297 *
298 *
299 * */
300
301
302;(function ( $, window, document, undefined ) {
303
304	var theinScroll = function(el, options){
305
306		var defaults = {
307
308            show: true,                                 // visibility custom scroll                                         [ true ], false
309            theme: "default",                           // theme custom sctoll                                              [ "default" ], "default-light"
310            rtl: false,                                 // right to left text direction                                     [ false ] / true
311            reservePlace: false,                        // reserve place for custom scroll                                  [ false ], true
312            autoHide: true,                             // auto hide custom scroll when losing hover                        [ true ], false
313            otherDirection: false,                      // display custom scroll from the other side than text direction    [ false ], true
314            addingIndent: 10,                           // additional indent for hiding the real scroll element             [ 
31410 ], number
315            scrollingDuration: 250,                     // duration scrolling animation                                     [ 250 ], number
316            slideDuration:  500,                        // add and clear content slide duration                             [ 500 ], number
317
318			buttons: {
319				up:                         false,          // view up button                           [ false ], true, any characters
320				scrollingUpSize:            '100',          // the value of the scroll content in px    [ '100' ], any number
321				down:                       false,          // view down button                         [ false ], true, any characters
322				scrollingDownSize:          '100'           // the value of the scroll content in px    [ '100' ], any number
323			},
324
325			endValues: {
326				up:                         false,          // end display unit scroll up               [ false ], true, any characters
327				down:                       false           // end display unit scroll down             [ false ], true, any characters
328			},
329
330			classes : {
331				main :	"the-in-scroll",
332				active: "m-active",
333				banSelect: "the-in__ban-drag-select",
334				banScroll: "the-in__ban-scroll"
335			},
336
337			triggers : {
338				'all' : false,
339				'initialized' : true,
340				'refresh' : true,
341				'refreshed' : true,
342				'up-pos' : true,
343				'down-pos' : true
344			}
345
346		};
347
348		/**
349		 * @create  { object }  this.$element           - main element
350		 * @create  { object }  this.defOptions         - default options
351		 * @create  { object }  this.userOptions        - user options
352		 * @create  { object }  this.options            - extend options
353		 * */
354		var _this = this;
355		_this.$element = $(el);
356		_this.defOptions = defaults;
357		_this.userOptions = options;
358		_this.options = $.extend(true, {}, defaults, options);
359		/**
360		 * Origin element
361		 * @protected
362		 */
363        _this._origin = false;
364
365		/** reserved names */
366		_this.prefix = '';
367		_this.pluginNumber = 0;
368		_this.frameResize = false;
369
370		_this.$wrBox = false;
371		_this.$box = false;
372		_this.$boxFrame = false;
373		_this.$container = false;
374		_this.$containerFrame = false;
375        _this.$content = false;
376		_this.$upEndValue = false;
377		_this.$downEndValue = false;
378		_this.$scroll = false;
379		_this.$scrollLine = false;
380		_this.$scroller = false;
381		_this.$scrollerTheme = false;
382
383        _this.addedTriggers = false;
384
385		_this.widthDefaultScroll = null;
386		_this.percentSizeScroller = null;
387		_this.stateScrollbarReservePlace = null;
388		_this.widthCustomScroll = null;
389		_this.percentSizeScroller = null;
390		_this.pxSizeScroller = null;
391		_this.sizeScrollLine = null;
392		_this.topPercentScrollContent = null;
393		_this.topPxScrollContent = null;
394		_this.topPercentScroller = null;
395		_this.topPxScroller = null;
396		_this.scrollingPercentage = null;
397
398		_this.startMoveScrollerPosition = null;
399		_this.currentMoveScrollerPosiiton = null;
400		_this.currentTopMoveScroller = null;
401		_this.startMoveYPosition = null;
402
403		this.init();
404	};
405	/**
406	 *  @update { String } this.prefix          - перфикс классов
407	 *  @update { String } this.pluginNumber    - уникальный класс с номером плагина
408	 *  @update { Object } this._origin         - сохранненная реальная верстка
409	 * */
410	theinScroll.prototype.init = function(){
411		var _this = this;
412	// create prefix classes
413		_this.prefix = _this.options.classes.main+'__';
414	// create a unique name
415		_this.pluginNumber = _this.prefix + $.now();
416	// save origin html
417		_this._origin = _this.$element.clone( true );
418	// detach content, add a new html, creation of selectors, return content and hide default scroll
419		_this.createMainHTML();
420	// create block end value scroll
421		_this.updateEndValues();
422	// create html custom scroll
423		if(_this.options.show) {
424			// add settings classes
425			if ( _this.options.autoHide )  _this.$element.addClass( _this.prefix + 'autohide' );
426			if ( _this.options.otherDirection )  _this.$element.addClass( _this.prefix + 'direction' );
427			if ( _this.options.reservePlace )  _this.$element.addClass(_this.prefix + 'reserve');
428			// create new custom scroll
429			_this.createCustomScroll();
430		}
431	// update status
432		_this.refresh();
433	// register events and listener
434		_this.registerEvents();
435		_this.registerEventsListener();
436	// trigger initialized
437		if ( _this.options.triggers.all || _this.options.triggers.initialized ) _this.setTrigger( 'initialized' )
438	};
439
440	theinScroll.prototype.registerEvents = function(){
441		var _this = this;
442		// resize box
443		window[ _this.pluginNumber + '__box' ].onresize = function(){
444			/* TODO remove */ //console.log('resize Frame update BOX ');
445			_this.resizeFrameRefresh();
446		};
447		// resize container
448		window[ _this.pluginNumber + '__container' ].onresize = function(){
449			/* TODO remove */ //console.log('resize Frame update CONTAINER');
450			_this.resizeFrameRefresh();
451		};
452		// scroll
453		_this.$box.bind( 'scroll' ,function(){
454			/* TODO remove */ //console.log('scroll update');
455			_this.refresh();
456		});
457		_this.$scroller.on( "touchstart  mousedown", function( event ) {
458			if ( event.type == "touchstart" ) {
459				_this.bindMoveScroller( event.originalEvent.touches[ 0 ].clientY || event.originalEvent.changedTouches[ 0 ].clientY );
460			} else if( event.type == "mousedown" && event.button == 0 ){
461				_this.bindMoveScroller( event.pageY );
462			}
463			// отменяем "всплытие сообщений", чтобы не вызывался клик на тач-устройствах.
464			event.stopPropagation();
465			event.preventDefault();
466		});
467		// mouse up on screen
468		$( window ).on( 'touchend  mouseup', function( event ){
469			if ( event.type == "touchend" || event.type == "mouseup" && event.button == 0) {
470				_this.unbindMoveScroller( event );
471			}
472		});
473	};
474
475	theinScroll.prototype.registerEventsListener = function(){
476		var _this = this;
477		_this.$element.on( 'scroll-to.' + _this.options.classes.main , function( event, position, duration ){
478			//console.log('--- scroll-to position= '+ position + ' - duration = '+ duration);
479			_this.scrollTo( position, duration );
480		});
481		_this.$element.on( 'scroll-up.' + _this.options.classes.main , function( event, position, duration ){
482			//console.log('scroll-up position= '+ position + ' - duration = '+ duration);
483			_this.scrollUp( position, duration );
484		});
485		_this.$element.on( 'scroll-down.' + _this.options.classes.main , function( event, position, duration ){
486			//console.log('scroll-down position= '+ position + ' - duration = '+ duration);
487			_this.scrollDown( position, duration );
488		});
489        _this.$element.on( 'add-scrolling-trigger.' + _this.options.classes.main , function( event, name, position, sign, down, everytime, move, once  ){
490            _this.addScrollingTrigger( name, position, sign, down, everytime, move, once  );
491        });
492        _this.$element.on( 'add-content.' + _this.options.classes.main , function( event, content, prep, slide, duration ){
493            _this.addContent( content, prep, slide, duration )
494        });
495        _this.$element.on( 'clear-content.' + _this.options.classes.main , function( event, slide, duration ){
496            _this.clearContent( slide, duration )
497        });
498	};
499
500	/**
501	 * @update  { object }  this._origin
502	 * @update  { string }  this.pluginNumber
503	 * @update  { object }  this.$wrBox
504	 * @update  { object }  this.$box
505	 * @update  { object }  this.$container
506	 * @update  { object }  this.$frame
507	 * */
508	theinScroll.prototype.createMainHTML = function(){
509        var _this = this;
510        // add base and theme classes
511        _this.$element
512            .addClass( _this.options.classes.main )
513            .addClass( _this.prefix + _this.options.theme );
514        // create html
515		_this.$wrBox = $( '<div class="' + _this.prefix + 'wr-box"></div>' );
516		_this.$box = $( '<div class="' + _this.prefix + 'box"></div>' );
517		_this.$container = $( '<div class="' + _this.prefix + 'container"></div>' );
518		_this.$content = $( '<div class="' + _this.prefix + 'content"></div>' );
519		_this.$boxFrame = $( '<iframe name="' + _this.pluginNumber + '__box" class="' + _this.prefix + 'frame"></iframe>' );
520		_this.$containerFrame = $( '<iframe name="' + _this.pluginNumber + '__container" class="' + _this.prefix + 'frame"></iframe>' );
521        _this.$element
522            .empty()
523            .css ( 'overflow', 'hidden' )
524            .append( _this.$wrBox.append( _this.$box.append( _this.$boxFrame , _this.$container.append( _this.$containerFrame, _this.$content ) ) ) );
525        // hide default scroll
526        _this.hideDefaultScroll();
527        // return content
528        _this.$content.append( _this._origin.clone( true )[ 0 ].childNodes );
529    };
530
531	/**
532	 * @update  { object }  this.$upEndValue
533	 * @update  { object }  this.$downEndValue
534	 * */
535	theinScroll.prototype.updateEndValues = function(){
536		var _this = this;
537
538		if ( _this.options.endValues.up ){
539			if ( !_this.$upEndValue ) _this.$upEndValue = $( '<div class="' + _this.prefix + 'end-value ' + _this.prefix + 'up-end-value"></div>' );
540			_this.$upEndValue.append( _this.options.endValues.up != true ? _this.options.endValues.up : '' );
541			_this.$wrBox.append( _this.$upEndValue );
542		}
543
544		if ( _this.options.endValues.down ){
545			if ( !_this.$downEndValue ) _this.$downEndValue = $( '<div class="' + _this.prefix + 'end-value ' + _this.prefix + 'down-end-value"></div>' );
546			_this.$downEndValue.append( _this.options.endValues.down != true ? _this.options.endValues.down : '' );
547			_this.$wrBox.append( _this.$downEndValue );
548		}
549
550	};
551
552	/**
553	 * @update  { object }  this.$scroll
554	 * @update  { object }  this.$scrollLine
555	 * @update  { object }  this.$scroller
556	 * @update  { object }  this.$scrollerTheme
557	 * @event   this.$scroll.contextmenu    - ban context menu on scrollbar
558	 * @event   this.$buttonUp.click        - change _this.$box.scrollTop
559	 * @event   this.$buttonDown.click      - change _this.$box.scrollTop
560	 * */
561	theinScroll.prototype.createCustomScroll = function(){
562		var _this = this;
563
564		_this.$scroll = $( '<div class="' + _this.prefix + 'scroll"></div>' );
565		_this.$scrollLine = $( '<div class="' + _this.prefix + 'scroll-line"></div>' );
566		_this.$scroller = $( '<div class="' + _this.prefix + 'scroller"></div>' );
567		_this.$scrollerTheme = $( '<div class="' + _this.prefix + 'scroller-theme"></div>' );
568		_this.$element.append( _this.$scroll.append( _this.$scrollLine.append( _this.$scroller.append( _this.$scrollerTheme ) ) ) );
569		// ban context menu on scroll bar
570		_this.$scroll.bind( 'contextmenu', function(){
571			return false;
572		});
573		// click on scroll line for scrolling
574		_this.$scrollLine.bind( 'click', _this, _this.scrollingByClickOnScrolline );
575		// add up button
576		if ( _this.options.buttons.up ){
577			_this.$buttonUp = $( '<a class="' +_this.prefix+ 'button ' + _this.prefix + 'button-up"></a>' );
578			_this.$buttonUp.append( _this.options.buttons.up != true ? _this.options.buttons.up : $( '<span class="' + _this.prefix + 'icon"></span>' ) );
579			_this.$scroll.append( _this.$buttonUp ).addClass( _this.prefix + 'with-up' );
580			_this.$buttonUp.click( function(){
581				_this.$box.scrollTop( _this.$box.scrollTop() - parseInt( _this.options.buttons.scrollingUpSize ) );
582			});
583		}
584		// add up button
585		if ( _this.options.buttons.down ){
586			_this.$buttonDown = $( '<a class="' +_this.prefix+ 'button ' + _this.prefix + 'button-down"></a>' );
587			_this.$buttonDown.append( _this.options.buttons.down != true ? _this.options.buttons.down : $( '<span class="' + _this.prefix + 'icon"></span>' ) );
588			_this.$scroll.append( _this.$buttonDown ).addClass( _this.prefix + 'with-down' );
589			_this.$buttonDown.click( function(){
590				_this.$box.scrollTop( _this.$box.scrollTop() + parseInt(_this.options.buttons.scrollingDownSize) );
591			});
592		}
593	};
594
595    /**
596     * Update all params
597     * */
598	theinScroll.prototype.refresh = function(){
599		var _this = this;
600		if ( _this.options.triggers.all || _this.options.triggers.refresh ) _this.setTrigger( 'refresh' );
601		_this.hideDefaultScroll();
602		if( _this.options.show ) {
603			_this.reservePlaceScroll();
604			_this.setSizeScroller();
605			_this.setTopScroller();
606		}
607		_this.scrollingPercentage = _this.getScrollingPercentage();
608		_this.checkExtremePositionScroller();
609        _this.checkAddedTriggers();
610		if ( _this.options.triggers.all || _this.options.triggers.refreshed ) _this.setTrigger( 'refreshed' );
611	};
612
613    /**
614     * @param { number | string }   to scrolling position
615     * @param { number }            duration animation
616     * */
617	theinScroll.prototype.scrollUp = function( position, duration ){
618	    //console.log( position  + ' '+ duration);
619		this.scrollTo( !position ? 0 : position, duration );
620	};
621
622    /**
623     * @param { number | string }   to scrolling position
624     * @param { number }            duration animation
625     * */
626	theinScroll.prototype.scrollDown = function( position, duration ){
627        var _this = this;
628        if ( !position || _this.$container.height() < _this.$box.height() ){
629            position = '100%';
630        } else {
631            position = this.toNumber(position);
632            if ( position !== false ){
633                position = _this.$container.height() - position - _this.$box.height();
634            } else {
635                position = '100%';
636            }
637        }
638        _this.scrollTo( position, duration );
639	};
640
641    /**
642     * @param { number | string }   to scrolling position
643     * @param { number }            duration animation
644     * */
645	theinScroll.prototype.scrollTo = function( position, duration ){
646		//console.log(' scrollTo = '+position+' dur = '+duration);
647		position = this.toNumber( position );
648		if ( position && position >= 0 || position == 0 ) {
649			// console.log('===== scrollTo = '+position);
650			var _this = this,
651				duration = ( duration == 0 || ( duration && duration >= 0 ) ) ? duration : _this.options.scrollingDuration;
652            //console.log('===== duration = '+duration);
653			_this.$box.stop().animate({
654				scrollTop: position
655			}, duration);
656		}
657	};
658
659	theinScroll.prototype.toNumber = function( number ){
660		var _this = this;
661		if ( !number ){
662			return false;
663		} else if ( typeof number == 'number' ){
664			return number >= 0 ? number : 0;
665		} else if ( typeof number == 'string' ){
666			if ( number.indexOf( '%' ) >= 0 ){
667				var	percent = parseInt( number.slice( 0, number.indexOf( '%' ) ) ),
668					size = ( _this.$container.height() >= _this.$box.height() ) ? _this.$container.height() - _this.$box.height() : 0;
669				return ( size / 100 * ( percent < 0 ? 0 : percent > 100 ? 100 : percent ) );
670			} else {
671				if ( parseInt( number ) >= 0 ) {
672					return parseInt( number );
673				} else {
674					return false;
675				}
676			}
677		}
678		return false;
679	};
680
681	/**
682	 * @update  { boolean }  this.frameResize
683	 * */
684	theinScroll.prototype.resizeFrameRefresh = function(){
685		var _this = this;
686		if ( !_this.frameResize ) _this.refresh();
687		_this.frameResize = true;
688		setTimeout(function(){
689			_this.frameResize = false;
690		}, 10);
691	};
692
693	/**
694	 * @update  { number }  this.startMoveScrollerPosition
695	 * @update  { number }  this.currentMoveScrollerPosiiton
696	 * @update  { number }  this.startMoveYPosition
697	 * */
698	theinScroll.prototype.bindMoveScroller = function( positionY ){
699		var _this = this;
700		_this.$scroller.addClass( _this.options.classes.active );
701		_this.startMoveScrollerPosition = parseInt( _this.$scroller.css( 'top' ) );
702		_this.currentMoveScrollerPosiiton = _this.startMoveScrollerPosition;
703		_this.startMoveYPosition = positionY;
704		if ( event.type == 'touchstart' ){
705			_this.banScroll();
706			$(window).bind( 'touchmove.the-in__scroll', _this, _this.dragScroller );
707		} else if ( event.type == 'mousedown' ){
708			_this.banDragSelect();
709			$(window).bind( 'mousemove.the-in__scroll', _this, _this.dragScroller );
710		}
711	};
712
713	theinScroll.prototype.unbindMoveScroller = function( event ){
714		var _this = this;
715		_this.$scroller.removeClass( _this.options.classes.active );
716		if ( event.type == "touchend" ) {
717			_this.banScroll( false );
718			$(window).unbind( 'touchmove.the-in__scroll', _this.dragScroller );
719		} else if( event.type == "mouseup" && event.button == 0 ){
720			_this.banDragSelect( false );
721			$(window).unbind( 'mousemove.the-in__scroll', _this.dragScroller );
722		}
723	};
724
725	/**
726	 * @update  { number }  this.currentTopMoveScroller
727	 * */
728	theinScroll.prototype.dragScroller = function( event ){
729		var _this = event.data,
730			pageY = _this.startMoveScrollerPosition;
731		if ( event.type == 'mousemove' ){
732			pageY = event.pageY;
733		} else if ( event.type == 'touchmove' ){
734			pageY = event.originalEvent.touches[ 0 ].clientY || event.originalEvent.changedTouches[ 0 ].clientY
735		}
736		var	newTopMoveScroller = _this.startMoveScrollerPosition - ( _this.startMoveYPosition - pageY ),
737			scrollingMaxLimit = _this.$scrollLine.height() - _this.pxSizeScroller;
738		if( newTopMoveScroller <= 0 ){
739			newTopMoveScroller = 0;
740		} else if( newTopMoveScroller >= scrollingMaxLimit ){
741			newTopMoveScroller = scrollingMaxLimit;
742		}
743		if ( _this.currentTopMoveScroller != newTopMoveScroller ){
744			_this.$scroller.css( 'top', newTopMoveScroller );
745			_this.currentTopMoveScroller = newTopMoveScroller;
746			_this.setScrollContent();
747		}
748	};
749
750	theinScroll.prototype.scrollingByClickOnScrolline = function(event){
751		var _this = event.data,
752		    scrollerUpperBound = _this.$scroller.offset().top,
753			scrollerLowerBound = scrollerUpperBound + _this.$scroller.outerHeight(),
754			mouseClick = event.pageY;
755		if ( mouseClick <= scrollerUpperBound ) {
756			_this.$box.scrollTop( _this.$box.scrollTop() - _this.$box.height() * 0.85 );
757		}
758		if ( mouseClick >= scrollerLowerBound ) {
759			_this.$box.scrollTop( _this.$box.scrollTop() + _this.$box.height() * 0.85 );
760		}
761	};
762
763	/**
764	 * @update  { number }  this.widthDefaultScroll
765	 * */
766	theinScroll.prototype.hideDefaultScroll = function(){
767		var _this = this,
768			widthDefaultScroll = Math.ceil( _this.$box.width() - _this.$container.outerWidth( true ) );
769		// recalculate the size if default width scroll line changed
770		if ( _this.widthDefaultScroll != widthDefaultScroll ){
771			_this.widthDefaultScroll = widthDefaultScroll;
772
773			if ( _this.options.rtl ) {
774				_this.$element.addClass( _this.prefix + 'rtl' );
775				_this.$box.css( 'margin-left', -( _this.widthDefaultScroll ) - _this.options.addingIndent ).css( 'margin-right', 0 );
776			} else {
777				_this.$element.removeClass( _this.prefix + 'rtl' );
778				_this.$box.css( 'margin-right', -( _this.widthDefaultScroll ) - _this.options.addingIndent ).css( 'margin-left', 0 );
779			}
780
781		}
782	};
783
784	/**
785	 * @update  { number }  this.stateScrollbarReservePlace
786	 * @update  { number }  this.widthCustomScroll
787	 * */
788	theinScroll.prototype.reservePlaceScroll = function(){
789		var _this = this,
790
791			widthCustomScroll = Math.ceil( _this.$scroll.outerWidth( true ) ),
792			stateScrollbarReservePlace = _this.options.reservePlace;
793
794		if ( _this.widthCustomScroll != widthCustomScroll || _this.stateScrollbarReservePlace != stateScrollbarReservePlace ){
795
796			_this.widthCustomScroll = widthCustomScroll;
797			_this.stateScrollbarReservePlace = stateScrollbarReservePlace;
798
799			if ( _this.options.reservePlace ){
800				var endValueCss,
801					boxPadding = ( _this.widthCustomScroll + _this.options.addingIndent ) + 'px' ;
802				if ( ( _this.options.rtl && !_this.options.otherDirection )
803						|| ( !_this.options.rtl && _this.options.otherDirection ) ) {
804					_this.$box.css( 'padding-left', boxPadding );
805					endValueCss = {
806						'left' : _this.widthCustomScroll + 'px',
807						'right': '0'
808					};
809					if ( _this.$upEndValue ) _this.$upEndValue.css( endValueCss );
810					if ( _this.$downEndValue ) _this.$downEndValue.css( endValueCss );
811				} else {
812					_this.$box.css( 'padding-right', boxPadding );
813					endValueCss = {
814						'right' : _this.widthCustomScroll + 'px',
815						'left': '0'
816					};
817					if ( _this.$upEndValue ) _this.$upEndValue.css( endValueCss );
818					if ( _this.$downEndValue ) _this.$downEndValue.css( endValueCss );
819				}
820			} else {
821				_this.$box
822					.css('padding','0')
823					.css( _this.options.rtl ? 'padding-left' : 'padding-right' , _this.options.addingIndent + 'px' );
824				if ( _this.$upEndValue ){
825					_this.$upEndValue.css({
826						'right': '0',
827						'left' : '0'
828					})
829				}
830				if ( _this.$downEndValue ){
831					_this.$downEndValue.css({
832						'right': '0',
833						'left' : '0'
834					})
835				}
836			}
837		}
838	};
839
840	/**
841	 * @update { number } this.percentSizeScroller
842	 * @update { number } this.pxSizeScroller
843	 * @update { number } this.sizeScrollLine
844	 * */
845	theinScroll.prototype.setSizeScroller = function(){
846		var _this = this,
847			percentSizeScroller = ( _this.$box.height() * 100 ) / _this.$container.outerHeight( true );
848		if ( _this.percentSizeScroller != percentSizeScroller ) {
849			_this.percentSizeScroller = percentSizeScroller;
850			if (_this.percentSizeScroller >= 100) {
851				_this.percentSizeScroller = 100;
852				if ( !_this.options.reservePlace ) {
853					_this.$scroll.hide();
854				}
855			} else {
856				_this.$scroll.show();
857			}
858			_this.sizeScrollLine = _this.$scrollLine.height();
859			_this.pxSizeScroller = Math.floor( ( _this.percentSizeScroller * _this.$scrollLine.height() ) / 100 );
860			_this.$scroller.outerHeight(_this.pxSizeScroller + 'px');
861		}
862	};
863
864	/**
865	 * @update { number } this.topPercentScroller
866	 * @update { number } this.topPxScroller
867	 * */
868	theinScroll.prototype.setTopScroller = function(){
869		var _this = this;
870		/* TODO remove */ //console.log('setTopScroller');
871		_this.topPxScrollContent = _this.$box.scrollTop();
872		_this.topPercentScroller = _this.topPercentScrollContent = ( _this.$box.scrollTop() * 100 ) / _this.$container.outerHeight( true );
873		_this.topPxScroller = Math.floor( ( _this.topPercentScroller * _this.$scrollLine.height() ) / 100 );
874		_this.$scroller.css( 'top', _this.topPxScroller + 'px' );
875	};
876
877	/**
878	 * @update { number } this.topPercentScrollContent
879	 * @update { number } this.topPxScrollContent
880	 * */
881	theinScroll.prototype.setScrollContent = function(){
882		var _this = this;
883		_this.topPercentScrollContent = ( parseInt( _this.$scroller.css( 'top' ) ) * 100 ) / _this.$scrollLine.outerHeight( true );
884		_this.topPxScrollContent = Math.ceil( ( _this.topPercentScrollContent * _this.$container.height() ) / 100 );
885		_this.$box.scrollTop( _this.topPxScrollContent );
886	};
887
888	theinScroll.prototype.checkExtremePositionScroller = function(){
889		var _this = this;
890		if (_this.$box.scrollTop() == 0) {
891			_this.$element.addClass( _this.prefix + 'up-pos' );
892			if ( _this.options.triggers.all || _this.options.triggers['up-pos'] ) _this.setTrigger( 'up-pos' );
893		} else {
894			_this.$element.removeClass( _this.prefix + 'up-pos' );
895		}
896		if ( ( _this.$box.scrollTop() + _this.$box.outerHeight() >=  _this.$container.outerHeight( true ) )
897			|| ( _this.$box.outerHeight() >= _this.$container.outerHeight( true ) ) ){
898			_this.$element.addClass( _this.prefix + 'down-pos' );
899			if ( _this.options.triggers.all || _this.options.triggers['down-pos'] ) _this.setTrigger( 'down-pos' );
900		} else {
901			_this.$element.removeClass( _this.prefix + 'down-pos' );
902		}
903	};
904
905	/**
906	 * Get scrolling percentage
907	 * Получить процент прокрутки
908	 * @return { number }
909	 * */
910	theinScroll.prototype.getScrollingPercentage = function(){
911		var diff = this.$container.outerHeight( true ) - this.$box.height(),
912			percentage = diff <= 0 ? 0 : ( this.$box.scrollTop() * 100 ) / diff;
913		return ( percentage > 100 ? 100 : percentage );
914	};
915
916    theinScroll.prototype.addContent = function( content, prepend, slide, duration ){
917        var _this = this;
918        if ( typeof content == 'string' ) content = $( content );
919        if ( typeof content == 'object' && !$.isPlainObject( content ) ) {
920            duration = ( duration >= 0 ) ? duration : _this.options.slideDuration;
921            if ( slide ) content.hide();
922            if ( prepend ) {
923                _this.$content.prepend( content );
924            } else {
925                _this.$content.append( content );
926            }
927            if ( slide ) content.slideDown( duration );
928        }
929    };
930
931    theinScroll.prototype.clearContent = function( slide, duration ){
932        var _this = this;
933        if ( slide ) {
934            duration = ( duration >= 0 ) ? duration : _this.options.slideDuration;
935            _this.$content.slideUp( duration, function(){
936                _this.$content.empty().show();
937            });
938        } else {
939            _this.$content.empty();
940        }
941    };
942
943	theinScroll.prototype.getCurrent = function(){
944		var _this = this,
945            data = {
946                'content' : {
947                    'position' : {
948                        'pc' : _this.topPercentScrollContent,
949                        'px' : _this.topPxScrollContent
950                    }
951                },
952                'scroller' : {
953                    'position' : {
954                        'pc' : _this.topPercentScroller,
955                        'px' : _this.topPxScroller
956                    },
957                    'size' : {
958                        'pc' : _this.percentSizeScroller,
959                        'px' : _this.pxSizeScroller
960                    }
961                },
962                'scrollingline' : {
963	                'size' : {
964                        'px' : _this.$scrollLine.height()
965                    }
966                },
967                'scrolling' : _this.scrollingPercentage
968            };
969        return data;
970	};
971
972    /**
973     *  Добавление тригера позиции прокрутки
974     *  @param { string | object }  trigger name or trigger data object
975     *  @param { number | string }  triggering position                     [ 0 ], 10, '10%'
976     *  @param { string }           triggering condition                    [ '<' ], '>'
977     *  @param { boolean }          direction of counting from below        [ false ], true
978     * */
979    theinScroll.prototype.addScrollingTrigger = function( name, position, sign, down, everytime, move, once ){
980        if ( name && ( typeof name.name == 'string' || typeof name == 'string' ) ){
981            if ( this.addedTriggers === false ) this.addedTriggers = {};
982            this.addedTriggers[ name.name || name ] = {
983                position : name.position || position || 0,
984                sign : ( name.sign == '<' || name.sign == '>' ) ? name.sign : ( sign == '<' || sign == '>' ) ? sign : '>',
985                down : name.down ? name.down : down ? down : false,
986                everytime : ( name.everytime && typeof name.everytime == 'boolean' ) ? name.everytime : ( everytime && typeof everytime == 'boolean' ) ? everytime : false,
987                move : ( name.move && typeof name.move == 'boolean' ) ? name.move : ( move && typeof move == 'boolean' ) ? move : false,
988                once : ( name.once && typeof name.once == 'boolean' ) ? name.once : ( once && typeof once == 'boolean' ) ? once : false
989            };
990            //  console.log(this.addedTriggers);
991        }
992    };
993
994    theinScroll.prototype.checkAddedTriggers = function( ) {
995        var _this = this;
996        if ( $.isPlainObject( _this.addedTriggers ) ) {
997            $.each( _this.addedTriggers, function ( n, v ) {
998                var show = false,
999                    position = parseInt( _this.toNumber( v.position ) ),
1000                    scroll = _this.$box.scrollTop();
1001
1002
1003                if ( position ) {
1004
1005                    if ( v.down ) scroll = _this.$container.height() - _this.$box.height() - scroll;
1006
1007                    if ( ( v.sign == '>' && scroll > position ) || ( v.sign == '<' && scroll < position ) ) {
1008
1009                        //console.log( (v.down ? 'DOWN' : 'UP')+' --- scroll '+v.sign+' position --- '+ scroll + ' '+v.sign+' '+ position);
1010
1011                        show = true;
1012
1013                    } else {
1014
1015                        if ( v.everytime === 1 ) v.everytime = true;
1016
1017                    }
1018
1019
1020                }
1021
1022
1023
1024                if ( show ) {
1025                    // console.log(n+' ---  move != scroll ( '+v.move+' != '+scroll+' = '+ (v.move !== scroll) + ')');
1026                    if ( v.everytime !== 1 && ( ( v.move !== scroll && v.move !== true ) || v.move === false ) ) _this.setTrigger(n);
1027                    if ( v.once ) delete _this.addedTriggers[ n ];
1028                    if ( v.everytime ) v.everytime = 1;
1029                }
1030
1031                if ( v.move !== false ) v.move = scroll;
1032
1033
1034
1035
1036            });
1037        }
1038    };
1039
1040	/**
1041	 * тригер
1042	 * triggers a public event.
1043	 * @param { String } event name
1044	 * @param { Object } data object
1045	 */
1046	theinScroll.prototype.setTrigger = function( name, data ){
1047		if ( typeof name != 'string' ) return false;
1048		var _this = this,
1049			extObj = $.extend ({
1050				"eventType" : name,
1051				"plugin" : _this
1052			}, _this.getCurrent()),
1053			data = ( $.isPlainObject( data ) ) ? $.extend( data, extObj ) : extObj;
1054		_this.$element.trigger( name + '.' + _this.options.classes.main , data );
1055	};
1056
1057	theinScroll.prototype.banDragSelect = function(state){
1058		$('body').toggleClass( this.options.classes.banSelect, state === false ? false : true );
1059	};
1060
1061	theinScroll.prototype.banScroll = function(state){
1062		$('body').toggleClass( this.options.classes.banScroll, state === false ? false : true );
1063	};
1064
1065	$.fn.theinScroll = function(options) {
1066		return this.each(function(){
1067			if(!$.data(this, 'theinScroll')){
1068				$.data(this, 'theinScroll', new theinScroll(this, options));
1069			}
1070		});
1071	};
1072
1073})( jQuery, window, document );
1074
1075
1076; "use strict";
1077
1078
1079/**
1080 * the-in Carousel version 2.0.0
1081 *
1082 *
1083 * Triggers on initialized object :
1084 *
1085 * initialize.the-in-carousel   - When the plugin initializes.
1086 * initialized.the-in-carousel  - When the plugin has ready to work.
1087 * resize.the-in-carousel       - When the plugin gets resized.
1088 * resized.the-in-carousel      - When the plugin has resized.
1089 * prev.the-in-carousel         - Goes to previous item.
1090 * next.the-in-carousel         - Goes to next item.
1091 * change.the-in-carousel       - When a property is going to change its value.
1092 * changed.the-in-carousel      - When a property has changed its value.
1093 * refresh.the-in-carousel      - When the internal state of the plugin needs update.
1094 * refreshed.the-in-carousel    - When the internal state of the plugin has updated.
1095 *
1096 *
1097 * Listener:
1098 *
1099 * prev.the-in-carousel         - previous item
1100 * next.the-in-carousel         - next item
1101 * parametr: [ duration {Number} ]
1102 * $('selector').click(function() {
1103 *     $('initialedCarouselSelector').trigger('next.the-in-carousel'[, 100]);
1104 * });
1105 * -----------------------------------------------------------
1106 * change.the-in-carousel       - changed carousel position
1107 * parametr: position {Number} [, duration {Number} ]
1108 * $('selector').click(function() {
1109 *     $('initialedCarouselSelector')trigger('change.the-in-carousel', 2 [, 100]);
1110 *     [ or ]
1111 *     $('initialedCarouselSelector')trigger('change.the-in-carousel', { position: 3 [, duration: 3000 ] });
1112 * });
1113 * -----------------------------------------------------------
1114 * refresh.the-in-carousel       - refresh carousel
1115 * parametr: [ forced recalculation of all parameters { Boolean } ]
1116 * $('selector').click(function() {
1117 *     $('initialedCarouselSelector').refresh('next.the-in-carousel'[, true]);
1118 * });
1119 * -----------------------------------------------------------
1120 *
1121 * !!! Attention !!!
1122 * motionType = 'scroll'    --->    sticked = false, elasticEnds = false
1123 * itemAutoWidth = true     --->    stretch = false, merge = false
1124 *
1125 * -----------------------------------------------------------
1126 *
1127 */
1128
1129
1130
1131;( function ( $, window, document, undefined ) {
1132
1133
1134	var theinCarousel = function ( element, options ) {
1135
1136		this.defOptions = theinCarousel.Defaults;
1137		this.userOptions = options;
1138		this.options = $.extend( true, {}, theinCarousel.Defaults, options );
1139
1140		/** Plugin element */
1141		this.$element = $( element );
1142
1143		/** Current settings */
1144		this.settings = null;
1145
1146		/** Origin elements - is created once */
1147		this._origin = {
1148			$element : false,
1149			$items : false,
1150			$html : false,
1151			length : false
1152		};
1153
1154		/** Current information */
1155		this._current = {
1156
1157			breakpoints: [ -1, 0 ],         // breakpoints interval
1158
1159			outsideLeft: false,             // indent outside left items
1160			outsideRight: false,            // indent outside right items
1161			between: false,                 // indent between items in line
1162
1163			rtl: false,                     // right to left flag
1164			active: 1,                      // current active position
1165
1166			maxActive: false,               // maximum active position for navigate and dots
1167
1168			loop: false,                    // current state loop
1169
1170			frameWidth: false,              // frame width
1171			frameFullWidth: false,          // frame width with between
1172			itemWidth: false,               // item width
1173			packWidth: false,               // pack width
1174			packFullWidth: false,           // pack width width center shift (x2) and elastic shift (x2)
1175
1176			scrollSize: false,              // высота скролла
1177
1178			motionType: false,              // тип перемещения/сдвига полосы слайдера
1179			motionTime: false,              // время на перемещение
1180
1181			$items: false,                  // items object
1182			itemsLength: 0,                 // number of items
1183
1184			// CLONE
1185			cloneBeforeLength: 0,           // number of clone items before origin
1186			cloneBeforeWidth: 0,            // width of clone items before origin
1187			cloneAfterLength: 0,            // number of clone items after origin
1188			cloneAfterWidth: 0,             // width of clone items after origin
1189
1190			limitMin: 0,                    //
1191			limitMax: 0,                    //
1192
1193			// centering
1194			center: false,                  // flag centering active item
1195			centerShiftBefore: false,       // size center shift for first element
1196			centerShiftAfter: false,        // size center shift for last element
1197
1198			// nav
1199			nav: false,                     //
1200			navContainer: false,            //
1201			navPosition: false,             //
1202			navText: false,                 //
1203
1204			// dots
1205			dots: false,                    //
1206			dotsNumber: 0,                  //
1207			dotsContainer: false,           //
1208			dotsPosition: false,            //
1209			dotsType: false,                //
1210
1211			// counter
1212			counter: false,                 // флаг показа счетчика
1213			counterContainer: false,        // селектор контейнера для отображения счетчика
1214			counterPosition: false,         // позиция вставки счетчика
1215			counterSeparator: false,        // разделитель цифр счетчика
1216
1217			// drag
1218			_drag: {
1219				itemStart: null,            //
1220				timeStart: null,            //
1221				shiftStart: null,           //
1222				touchStart: null,           //
1223				delta: 0,                   //
1224				checkDirection: null        //
1225			}
1226
1227		};
1228
1229		/** Current state information */
1230		this._state = {
1231			current: {
1232				initialize: 0,
1233				refresh: 0,
1234				scrolling: 0,
1235				change: 0,
1236				grab: 0,
1237				drag: 0,
1238				prev: 0,
1239				next: 0,
1240				touch: 0
1241			},
1242			tags: {
1243				/*
1244				'initializing': [ 'busy' ],
1245				'animating': [ 'busy' ],
1246				'dragging': [ 'interacting' ]
1247				*/
1248			}
1249		};
1250
1251		/**
1252		 * Proxied event handlers
1253		 * */
1254		this._handlers = {};
1255		$.each( [ 'onResize', 'delayResizeUpdate' ], $.proxy( function ( i, handler ) {
1256			this._handlers[ handler ] = $.proxy( this[ handler ], this );
1257		}, this ) );
1258
1259		this.initialize();
1260	};
1261
1262	/**
1263	 * Default options for the carousel.
1264	 * @public
1265	 */
1266	theinCarousel.Defaults = {
1267
1268		/** classes */
1269		classes: {
1270			main: 'the-in-carousel',
1271			active: 'm-active',
1272			disabled: 'm-disabled',
1273			scroll: 'm-scroll',
1274			clone: 'm-clone'
1275		},
1276
1277		/** once once during the start */
1278		/** используются только при инициализации  */
1279		startPosition: false,           // стартовый слайд - используется только при инициализации          [ false ] / number
1280		/** TODO ???? */
1281		//showAllTriggers : true,       // показывать все тригерры                                          [ false ] / true
1282
1283		/** every time during the rebuilding */
1284		/** используются каждый раз при перестроении */
1285
1286		nestedItemSelector: '>',        // селектор для выбора вложенного элементов                         [ false ] / string
1287
1288		/** Items priority: taken first found */
1289		/** Преоритет использование параметров: при нескольких заполненных берется первый найденный */
1290		/** itemAutoWidth -> itemMinWidth -> itemWidth -> items */
1291
1292		itemAutoWidth: false,           // auto width items                                                 [ false ] / true
1293		itemMinWidth: false,            // min width item                                                   [ false ] / number
1294		itemWidth: false,               // width item                                                       [ false ] / number
1295		items: 1,                       // number items on screen                                           [ 
12951 ] / number
1296
1297		slideBy: 1,                     // на сколько сдвигать                                              [ 1 ] / number
1298
1299		/** motion settings */
1300		motionType: 'transform',        // тип сдвига                                                       [ 'transform' ] / 'animate' / 'scroll'
1301		motionTime: 200,                // время анимации смены слайда
1302
1303		between: 0,                     // отступы между элементами                                         [ 0 ] / number / number with percent symbol '10%'
1304		outside: 0,                     // отступ снаружи элементов                                         [ 0 ] / number / number with percent symbol '10%'
1305		outsideLeft: false,             // отступ снаружи слева от элементов                                [ 0 ] / number / number with percent symbol '10%'
1306		outsideRight: false,            // отступ снаружи справа от элементов                               [ 0 ] / number / number with percent symbol '10%'
1307
1308		/** behavior settings */
1309		stretch: false,                 // элементы тянутся на всю ширину если меньше ширины контейнера     [ false ] / true
1310		autoWidthNoStretch: true,       // [ true ] / false
1311		sticked: true,                  // элементы прилипают к краю                                        [ true ] / false
1312		scaling: false,                 // элемент не должен быть больше frame по ширине при auto width     [ false ] / true
1313		merge: true,                    // растягивать элемент на несколько позиций из data-merge           [ true ] / true
1314		elasticEnds: false,             // эластичный оттягивание на концах                                 [ true ] / true
1315		center: false,                  // центровать активный слайд                                        [ false ] / true
1316		lessCenter : false,             // центровать элементы если меньше ширины фрейма                    [ false ] / false
1317		loop: false,                    // прокрутка по кругу                                               [ false ] / true
1318		rewind: false,                  // прокрутка на другой конец когда достигнута граница               [ false ] / true
1319		rtl: false,                     // правонаправленный                                                [ false ] / true
1320
1321		deactivate: false,              // отключить слайдер вернуть верстку                                [ false ] / true
1322
1323		/** navigate buttons settings */
1324		nav: true,                      // формировать / показывать блок навигации                          [ false ] / true
1325		navContainer: false,            // контейнер для вывода навигации                                   [ false ] / string  ( selector )
1326		navPosition: 'after',           // позиция для вывода блока нвигации                                [ 'after' | false ] / 'before'
1327		navTag: 'button',               // название тега для кнопки навигации                               [ 'button' ] / string ( tagname )
1328		navText: [ 'prev', 'next' ],    // текст для кнопок навигации                                       [ array ] / false
1329
1330		/** settings navigate dots */
1331		dots: false,                    // формировать / показывать блок навигационных точек                [ false ] / true / 'each'
1332		dotsContainer: false,           // контейнер для вывода навигационных точек                         [ false ] / string ( selector )
1333		dotsPosition: 'after',          // позиция для вывода блока навигационных точек                     [ 'after' | false ] / 'before'
1334		dotsType: false,                // тип навигационных точек                                          [ false ] / 'number'
1335
1336		/** settings counter */
1337		counter: false,                 // формировать / показывать блок счетчика                           [ false ] / true
1338		counterContainer: false,        // контейнер для вывода блока счетчика                              [ false ] / true ( selector )
1339		counterPosition: 'after',       // позиция для вывода блока счетчика                                [ 'after' | false ] / 'before'
1340		counterSeparator: '/',          // разделитель цифр счетчика                                        [ '/' ] / string
1341
1342		/** responsive settings */
1343		responsive: {},                 // настройки для адаптивного дизайна                                [ object ] / settings object
1344		responsiveRefreshRate: 200,     // время задержки перед трансформацией                              [ 200 ] / number
1345		responsiveBaseElement: false,   // использовать для responsive ширину frame (true) или другого элемента (selector)          [ false ] / true / 'selector'
1346
1347		/** developers settings */
1348		showStates: 'false'    // селектор куда вывести блок состояний [ false ] / 'id selector'
1349
1350	};
1351
1352	/**
1353	 *
1354	 * @property {Object}           this.$element                   - елемент на котором была инициализация
1355	 *
1356	 * @property {Object}           this._origin.$element           - оригинальная верстка
1357	 * @property {Object}           this._origin.$html              - блок с клоном реальной верстки для возврата
1358	 * @property {Object}           this._origin.$items             - набор оригинальных итемов
1359	 * @property {Object}           this._origin.length             - кол-во реальных элементов
1360	 *
1361	 * @property {Object}           this.$el                        - слайдер
1362	 * @property {String}           this.prefix                     - префикс для классов
1363	 * @property {String}           this.pluginNumber               - класс номер плагина
1364	 * @property {Boolean}          this.isMobile                   - флаг что мобильный браузер
1365	 * @property {Boolean}          this.isTransform                - флаг что браузер поддерживает transform
1366	 *
1367	 * @property {Number}           this.cancelUpdate               - флаг не обновлять значение при иземенениях фрейма
1368	 *
1369	 * @property {Object}           this.$sizeFrame                 - фрейм для считывания изменений габаритных размеров виджета
1370	 * @property {Object}           this.$wrFrame                   -
1371	 * @property {Object}           this.$frame                     - рамка в которой двидется полоса с элементами
1372	 * @property {Object}           this.$stage                     - вспомогательная обертка
1373	 * @property {Object}           this.$pack                      - полоса с элментами
1374	 * @property {Object}           this.$nav                       - навигация
1375	 * @property {Object}           this.$navPrev                   - кнопка предыдущий
1376	 * @property {Object}           this.$navNext                   - кнопка следующий
1377	 * @property {Object}           this.$dots                      - блок с навигационными точками
1378	 * @property {Object}           this.$dotsDot                   - навигационнаые точки
1379	 * @property {Object}           this.$counter                   - счетчик элементов
1380	 * @property {Object}           this.$counterOf                 - текущее значени
1381	 * @property {Object}           this.$counterSep                - разделитель значений
1382	 * @property {Object}           this.$counterMax                - максимальное значение
1383	 *
1384	 * @property {Object}           this._current                   - текущие состояния
1385	 * @property {Array}            this._current.breakpoints       - промежуток
1386	 * @property {Number}           this._current.scrollSize        - высота скрола
1387	 * @property {Number}           this._current.outsideLeft       - отступ слева от элементов
1388	 * @property {Number}           this._current.outsideRight      - отступ справа от элементов
1389	 * @property {Number}           this._current.between           - отступы между элементами
1390	 * @property {Boolean}          this._current.rtl               - флаг что правонаправленный
1391	 * @property {Boolean}          this._current.active            - номер активного элемента
1392	 * @property {Number}           this._current.maxActive         - маскимально вохможный активный элмент для прокрутки
1393	 * @property {Boolean}          this._current.loop              - флаг крутить по кругу
1394	 * @property {Number}           this._current.frameWidth        -
1395	 * @property {Number}           this._current.frameFullWidth    -
1396	 * @property {Number}           this._current.itemWidth         -
1397	 * @property {Number}           this._current.packWidth         -
1398	 * @property {Number}           this._current.packFullWidth     -
1399	 * @property {Object}           this._current.$items            -
1400	 * @property {Object}           this._current.slideBy           -
1401	 * @property {Number}           this._current.itemsLength       -
1402	 * @property {Number}           this._current.visibleItems      -
1403	 * @property {Number}           this._current.clonedLength      -
1404	 *
1405	 * @property {String}           this._current.motionType        -
1406	 * @property {Number}           this._current.motionTime        -
1407	 *
1408	 * @property {Boolean}          this._current.nav               -
1409	 * @property {Boolean|String}   this._current.navContainer      -
1410	 * @property {String}           this._current.navPosition       -
1411	 * @property {Boolean|Array}    this._current.navText           -
1412	 *
1413	 * @property {Boolean}          this._current.dots              -
1414	 * @property {Number}           this._current.dotsNumber        -
1415	 * @property {Boolean|String}   this._current.dotsContainer     -
1416	 * @property {Boolean|String}   this._current.dotsPosition      -
1417	 * @property {Boolean|String}   this._current.dotsType          -
1418	 *
1419	 * @property {Boolean|String}   this._current.counter           -
1420	 * @property {Boolean|String}   this._current.counterContainer  -
1421	 * @property {Boolean|String}   this._current.counterPosition   -
1422	 * @property {Boolean|String}   this._current.counterSeparator  -
1423	 * */
1424
1425	theinCarousel.prototype.initialize = function () {
1426		var _this = this;
1427
1428		/** short class name and remove long*/
1429		_this.cl = _this.options.classes;
1430		delete _this.options.classes;
1431
1432		/* TODO for developer */
1433		if ( _this.options.showStates && typeof _this.options.showStates == 'string' ) _this.defShowStates = _this.showStates;
1434		/* TODO for developer */
1435
1436		/** start initialize*/
1437		_this.enterState('initialize');
1438		_this.setTrigger('initialize');
1439
1440		/** prefix class */
1441		_this.prefix = _this.cl.main + '__';
1442		/** pluginNumber - plugin number */
1443		_this.pluginNumber = _this.prefix + $.now();
1444		/** isMobile - flag mobile browser */
1445		_this.isMobile = _this.mobileBrowser() || false;
1446		/** isTransform - flag can use transform style */
1447		_this.isTransform = _this.supportsCSS( 'transform', 'translate3d(0px, 0px, 0px)' ) && _this.supportsCSS( 'transition', 'all 250ms ease 0s' );
1448
1449		/** Создаем верстку основных блоков */
1450		_this.createHtml();
1451		/** Получаем настройки для текущего разрешения */
1452		_this.getSettings( true );
1453		/** Создаем оригинальные элементы в соотвествии с полученными настройками для разрешения Выполнять строго после _this.getSettings( true ); */
1454		_this.itemsUpdate();
1455
1456		/** get active item number */
1457		_this._current.active = ( _this.options.startPosition > 0 && _this.options.startPosition <= _this._origin.length ) ? _this.options.startPosition : 1;
1458		_this._current.activePosition = _this._current.active;
1459
1460		/** create navigate elements carousel */
1461		_this.navCreate();
1462		_this.dotsCreate();
1463		_this.counterCreate();
1464
1465		/** register  */
1466		_this.registerListenerEvents();
1467		_this.registerEvents(); // обязательно тут или с задержкой!!!
1468		_this.dragRegisterEvents();
1469
1470		/* TODO REMOVE */ //console.log( 'ADD CLASS READY ' );
1471
1472		_this.$el.addClass( _this.prefix + 'ready' );
1473		_this.$element.addClass( _this.prefix + 'ready' );
1474
1475		/** первое принудительное обновление */
1476		_this.onResize( true );
1477
1478		_this.leaveState( 'initialize' );
1479		_this.setTrigger( 'initialized' );
1480
1481
1482	};
1483	/**
1484	 * Receiving settings based on screen resolution, frame or other block ( selector: responsiveBaseElement );
1485	 * Получение настроек в зависимости от разрешения экрана, frame блока или другого блока ( селектор: responsiveBaseElement );
1486	 * @param {Boolean} forced update
1487	 * @return {Object} settings
1488	 * @update {Object} _this.settings - settings
1489	 */
1490	theinCarousel.prototype.getSettings = function ( forced ) {
1491		var _this = this,
1492			viewWidth = _this.viewportWidth(); // ширина viewport или другого блока по ширине которого применяются настройки responsive
1493		if ( forced || _this.settings == null || viewWidth <= _this._current.breakpoints[ 0 ] || viewWidth > _this._current.breakpoints[ 1 ] ) {
1494			var overwrites = _this.options.responsive,
1495				settings = null;
1496			if ( !overwrites ) {
1497				settings = $.extend( {}, this.options );
1498				_this._current.breakpoints = [ 0, Infinity ];
1499			} else {
1500				var match = -1,
1501					pointsArray = [],
1502					pointsKey = -1;
1503				$.each(overwrites, function ( point ) {
1504					pointsArray.push( Number( point ) );
1505					if ( viewWidth >= point && match < point ) {
1506						pointsKey++;
1507						match = Number( point );
1508					}
1509				});
1510				_this._current.breakpoints = [ pointsArray[ pointsKey ] ? pointsArray[ pointsKey ] : 0, pointsArray[ ( pointsKey + 1 ) ] ? pointsArray[ ( pointsKey + 1 ) ] : Infinity ];
1511				settings = $.extend( {}, _this.options, overwrites[ match ] );
1512				delete settings.responsive;
1513				// проверяем наличие размеров элементов слайдера для разрешения и при наличии заменяем дефолтные настройки
1514				if ( overwrites[ match ] && ( overwrites[ match ].itemAutoWidth || overwrites[ match ].itemMinWidth || overwrites[ match ].itemWidth || overwrites[ match ].items ) ) {
1515					$.each( [ 'itemAutoWidth', 'itemMinWidth', 'itemWidth', 'items' ], function( i, v){
1516						settings[ v ] = overwrites[ match ][ v ] ? overwrites[ match ][ v ] : false;
1517					});
1518					//console.log( _this.options.itemAutoWidth, _this.options.itemMinWidth , _this.options.itemWidth , _this.options.items );
1519					//console.log( overwrites[ match ].itemAutoWidth, overwrites[ match ].itemMinWidth , overwrites[ match ].itemWidth , overwrites[ match ].items );
1520					//console.log( settings.itemAutoWidth, settings.itemMinWidth , settings.itemWidth , settings.items );
1521				}
1522			}
1523			_this.settings = settings;
1524		}
1525		//console.log( _this.settings );
1526		return _this.settings;
1527	};
1528	/**
1529	 * Register events listeners
1530	 */
1531	theinCarousel.prototype.registerListenerEvents = function () {
1532		var _this = this;
1533		_this.$element.on( 'prev.' + _this.cl.main, function ( event, data ) {
1534			var duration = ( data && typeof data == 'number' && data >= 0 ) ? data : false;
1535			if ( !_this.isState( 'prev' ) ) {
1536				_this.enterState( 'prev' );
1537				_this.prev( duration );
1538				_this.leaveState( 'prev' );
1539			}
1540		});
1541		_this.$element.on( 'next.' + _this.cl.main, function ( event, data ) {
1542			var duration = (data && typeof data == 'number' && data >= 0) ? data : false;
1543			if (!_this.isState( 'next' )) {
1544				_this.enterState( 'next' );
1545				_this.next(duration);
1546				_this.leaveState( 'next' );
1547			}
1548		});
1549		_this.$element.on( 'change.' + _this.cl.main, function ( event, data, dataDuration ) {
1550			var position = false,
1551				duration = false;
1552			if ( data ) {
1553				if ( $.isPlainObject( data ) ) {
1554					if ( data.position && typeof data.position == 'number' && data.position >= 1 ) position = data.position;
1555					if ( data.duration && typeof data.duration == 'number' && data.duration >= 0 ) duration = data.duration;
1556				} else {
1557					if ( typeof data == 'number' && data >= 1 ) {
1558						position = data;
1559					}
1560					if ( typeof dataDuration == 'number' && data >= 0 ) {
1561						duration = dataDuration;
1562					}
1563				}
1564			}
1565			if ( position && !_this.isState( 'change' ) ) {
1566				_this.enterState( 'change' );
1567				_this.change( position, duration );
1568				_this.leaveState( 'change' );
1569			}
1570		});
1571		_this.$element.on( 'refresh.' + _this.cl.main, function ( event, data ) {
1572			var forced = data ? true : false;
1573			if (!_this.isState( 'refresh' )) {
1574				_this.onResize( forced );
1575			}
1576		});
1577	};
1578	/**
1579	 * Registry events handlers
1580	 * Регистрация эвентов
1581	 */
1582	theinCarousel.prototype.registerEvents = function () {
1583		var _this = this;
1584		/*window[ _this.pluginNumber ].onresize = function () {
1585			if ( _this.cancelUpdate ) {
1586				_this.cancelUpdate = false;
1587			} else {
1588				_this._handlers.delayResizeUpdate();
1589			}
1590		};*/
1591		if ( !_this.options.responsiveBaseElement ) {
1592			$( window ).on( 'resize', function () {
1593				_this.cancelUpdate = true;
1594				_this._handlers.delayResizeUpdate();
1595			});
1596		}
1597		_this.$frame.on( 'scroll', function () {
1598			_this.dragScrolling();
1599		})
1600	};
1601	/**
1602	 * Checks window `resize` event.
1603	 * Задержка выполнения апдейта
1604	 * @protected
1605	 */
1606	theinCarousel.prototype.delayResizeUpdate = function () {
1607		var _this = this;
1608		_this.setTrigger( 'resize' );
1609		window.clearTimeout( _this.resizeTimer );
1610		_this.resizeTimer = window.setTimeout( _this._handlers.onResize, _this.settings.responsiveRefreshRate );
1611	};
1612	/**
1613	 * Checks window or frame `resize` event.
1614	 * @protected
1615	 */
1616	theinCarousel.prototype.onResize = function ( forced ) {
1617		var _this = this;
1618		if (_this.$element.is(':visible')) {
1619			_this.enterState('refresh');
1620			_this.setTrigger('refresh');
1621
1622			_this.refresh( forced );
1623
1624			_this.navRefresh();
1625			_this.dotsRefresh();
1626			_this.counterRefresh();
1627
1628			_this.leaveState('refresh');
1629			_this.setTrigger('refreshed');
1630		}
1631	};
1632
1633	/** ---------- CREATE HTML ---------- */
1634	/**
1635	 * Save origin element and create html origin element
1636	 * @update {Object} _this._origin.$element
1637	 * @update {Object} _this._origin.$html
1638	 */
1639	theinCarousel.prototype.createOrigins = function ( elem ) {
1640		this._origin.$element = typeof elem == 'object' ? elem : this.$element.clone(true);
1641		this._origin.$html  = $( '<div class="' + this.cl.main + ' ' + this.pluginNumber + ' ' + this.prefix + 'origin"></div>' ).append( this._origin.$element.clone( true )[ 0 ].childNodes );
1642	};
1643	/**
1644	 * creating main html
1645	 * @update {Object} this.$sizeFrame
1646	 * @update {Object} this.$el
1647	 * @update {Object} this.$frame
1648	 * @update {Object} this.$stage
1649	 * @update {Object} this.$pack
1650	 * */
1651	theinCarousel.prototype.createHtml = function () {
1652		var _this = this;
1653		if ( !_this._origin.$element ) _this.createOrigins();
1654		_this.$element.empty();
1655		// create objects
1656		_this.$el = $( '<div class="' + _this.cl.main + ' ' + _this.pluginNumber + '"></div>' );
1657		// add attr "title" on iframe for test LightHouse #RIA2018-2783
1658		_this.$sizeFrame = $( '<iframe title="frame" name="' + _this.pluginNumber + '" class="' + _this.prefix + 'size-frame"></iframe>' );
1659		_this.$stage = $( '<div class="' + this.prefix + 'stage"/>' );
1660		_this.$frame = $( '<div class="' + this.prefix + 'frame"/>' );
1661		_this.$pack = $( '<div class="' + this.prefix + 'pack"/>' );
1662		// assembly of layout
1663		_this.$element.append( _this.$el.append( _this.$sizeFrame, _this.$stage.append( _this.$frame.append( _this.$pack ) ) ) );
1664
1665	};
1666	/**
1667	 * @update {Object} this._origin.$items
1668	 * @update {Object} this._origin.length
1669	 * @update {Object} this._current.nestedItemSelector
1670	 * */
1671	theinCarousel.prototype.itemsUpdate = function ( forced ) {
1672		var _this = this,
1673			s = _this.settings,
1674			c = _this._current;
1675		if ( forced || !this._origin.$items || ( c.nestedItemSelector != s.nestedItemSelector ) ) {
1676			c.nestedItemSelector = s.nestedItemSelector;
1677			/* TODO REMOVE */ //console.log('▲▲▲ UPDATE ITEMS ▲▲▲ nestedItemSelector = ' + c.nestedItemSelector + ' ▲ $el = ', this.$el);
1678			this._origin.$items = this._origin.$element.find( typeof c.nestedItemSelector == 'string' ? c.nestedItemSelector : '>' ).clone( true );
1679			this._origin.length  = this._origin.$items.length;
1680			_this.itemsReplace();
1681		}
1682	};
1683	/**
1684	 * creating elements and inserting into a pack
1685	 * @update {Object} this.$itemsOrigin
1686	 * */
1687	theinCarousel.prototype.itemsReplace = function () {
1688		var _this = this;
1689		_this.$pack.empty();
1690		_this._origin.$items.each( function ( index, value ) {
1691			_this.$pack.append( _this.itemCreate( value, ( index + 1 ) ) );
1692		});
1693		_this.$itemsOrigin = $('.' + _this.prefix + 'item:not(.' + _this.cl.clone + ')', _this.$pack );
1694	};
1695	/**
1696	 * @param {Object} obj carousel item
1697	 * @param {Number} index carousel item
1698	 * @return {Object} carousel item object
1699	 * */
1700	theinCarousel.prototype.itemCreate = function ( obj, index ) {
1701		var item = $( '<div class="' + this.prefix + 'item" data-item="' + index + '"></div>' ).append( $( obj ).clone( true ) ),
1702			queue = [ 'merge', 'no-stretch' ]; // очередь data атрибутов для копирования на элемент карусели
1703		$.each( queue, function( i, v ){
1704			var d = $( obj ).data( v );
1705			if ( d !== 'undefined' ) item.attr( 'data-' + v, d );
1706		});
1707		return ( item );
1708	};
1709
1710	/** ---------- MOTION TYPE ---------- */
1711	/**
1712	 * @update this._current.motionType
1713	 * @update this._current.motionTime
1714	 */
1715	theinCarousel.prototype.motionRefresh = function () {
1716		var c = this._current,
1717			s = this.settings,
1718			t = 'motionType',
1719			i = 'motionTime';
1720		if ( c[ i ] != s[ i ] )
1721			c[ i ] = s[ i ];
1722		if ( c[ t ] != s[ t ] ) {
1723			if ( s[ t ] != 'animate' && s[ t ] != 'transform' && s[ t ] != 'scroll' ) s[ t ] = this.defOptions[ t ];
1724			if ( s[ t ] == 'transform' && !this.isTransform ) s[ t ] = 'animate';
1725			var from = c[ t ],
1726				to = s[ t ];
1727			c[ t ] = s[ t ];
1728			this.motionChangeType( from, to );
1729		}
1730	};
1731	theinCarousel.prototype.motionChangeType = function ( from, to ) {
1732		var _this = this,
1733			c = _this._current;
1734		if ( from == 'scroll' ) {
1735			/* TODO remove */ //console.log(' === FROM === scroll');
1736			_this.$frame.stop().removeClass( _this.cl.scroll );
1737			_this.$el.removeClass( _this.prefix + 'rtl' );
1738			_this.$frame.scrollLeft( 0 );
1739			_this.$el.toggleClass( _this.prefix + 'rtl', _this.settings.rtl );
1740			c.scrollSize = 0;
1741			_this.$frame.css({
1742				'margin-bottom': '',
1743				'padding-bottom': ''
1744			});
1745		} else if ( from == 'transform' ) {
1746			/* TODO remove */ //console.log(' === FROM === transform');
1747			_this.setStyle( _this.$pack, {
1748				transition: '',
1749				transform: ''
1750			})
1751		} else {
1752			/* TODO remove */ //console.log(' === FROM === animate');
1753			_this.$pack.stop().css( 'left', '' );
1754		}
1755		if ( to == 'scroll' ) {
1756			_this.$frame.addClass(_this.cl.scroll);
1757			var additive = 10,
1758				scrollSize = _this.$pack.height() - _this.$frame.height() - additive;
1759			if ( scrollSize != c.scrollSize ) {
1760				c.scrollSize = scrollSize;
1761				_this.$frame.css({
1762					'margin-bottom': scrollSize + 'px',
1763					'padding-bottom': additive + 'px'
1764				});
1765			}
1766		}
1767		/* TODO remove */ //console.log( '++++++++++ change position -> motionChangeType -> '+from+' -> '+to);
1768		if ( !_this.isState( 'initialize' ) ) {
1769			_this.change( c.active, true );
1770		}
1771	};
1772
1773	/** ---------- NAVIGATE ---------- */
1774	/**
1775	 * @create this.$nav
1776	 * @create this.$navPrev
1777	 * @create this.$navNext
1778	 */
1779	theinCarousel.prototype.navCreate = function () {
1780		var _this = this;
1781		if ( _this.settings.nav ) {
1782			if ( _this.$nav ) _this.$nav.remove();
1783			_this.$nav = $( '<div class="' + _this.prefix + 'nav"></div>' );
1784			// add attr "name" on button for test LightHouse #RIA2018-2783
1785			_this.$navPrev = $( '<' + _this.settings.navTag + 'name="prev"' + ' class="' + _this.prefix + 'nav-button ' + _this.prefix + 'nav-prev"></' + _this.settings.navTag + '>' );
1786			_this.$navNext = $( '<' + _this.settings.navTag + 'name="next"' + ' class="' + _this.prefix + 'nav-button ' + _this.prefix + 'nav-next"></' + _this.settings.navTag + '>' );
1787			_this.$nav.append( _this.$navPrev, _this.$navNext );
1788			_this.navRefresh();
1789			_this.navAddEvents();
1790			_this.setTrigger( 'navCreate' );
1791		}
1792	};
1793	/**
1794	 * @update this._current.navText
1795	 */
1796	theinCarousel.prototype.navRefresh = function () {
1797		var _this = this,
1798			c = _this._current,
1799			s = _this.settings;
1800		if ( _this.settings.nav && !_this.$nav ) _this.navCreate();
1801		if ( _this.$nav ) {
1802			_this.refreshAddedElements( 'nav' );
1803			if ( s.nav && Array.isArray( s.navText ) && s.navText.length >= 2 && c.navText != s.navText ) {
1804				/* TODO remove */ //console.log('<<<<< navRefresh >>>>> change TEXT');
1805				_this.$navPrev.empty().html( s.navText[ 0 ] );
1806				_this.$navNext.empty().html( s.navText[ 1 ] );
1807				c.navText = s.navText;
1808			}
1809			_this.navSetActive();
1810		}
1811	};
1812	theinCarousel.prototype.navAddEvents = function () {
1813		var _this = this;
1814		if ( _this.$navNext ) {
1815			_this.$navNext.on( 'click', function () {
1816				_this.next();
1817			});
1818		}
1819		if ( _this.$navPrev ) {
1820			_this.$navPrev.on('click', function () {
1821				_this.prev();
1822			});
1823		}
1824	};
1825	theinCarousel.prototype.navSetActive = function () {
1826		if ( this.$nav ) {
1827			var _this = this,
1828				c = _this._current,
1829				prevActive = c.active > 1,
1830				nextActive = c.active < c.maxActive,
1831				active = c.loop || c.rewind;
1832			if ( c.motionType == 'scroll' ) {
1833				var packShift = _this.getPackShift().x;
1834				prevActive = c.rtl ? packShift < c.limitMax : packShift > c.limitMin ;
1835				nextActive = c.rtl ? packShift >
1835 c.limitMin : packShift < c.limitMax ;
1836			}
1837			_this.$navPrev.toggleClass( _this.cl.active, active || ( prevActive && c.maxActive > 1 ) );
1838			_this.$navNext.toggleClass( _this.cl.active, active || ( nextActive && c.maxActive > 1 ) );
1839			_this.$nav.toggleClass( _this.cl.active, c.maxActive > 1 );
1840			_this.$element.toggleClass( _this.prefix + 'with-nav', c.maxActive > 1 );
1841			_this.$el.toggleClass( _this.prefix + 'with-nav', c.maxActive > 1 );
1842		}
1843	};
1844
1845	/** ---------- DOTS ---------- */
1846	/**
1847	 * @create this.$dots
1848	 */
1849	theinCarousel.prototype.dotsCreate = function () {
1850		var _this = this;
1851		if ( _this.settings.dots ) {
1852			if ( _this.$dots ) _this.$dots.remove();
1853			_this.$dots = $( '<div class="' + _this.prefix + 'dots"></div>' );
1854			_this.dotsRefresh();
1855			_this.dotsAddEvents();
1856
1857		}
1858	};
1859	/**
1860	 * @update this._currents.dotsType
1861	 */
1862	theinCarousel.prototype.dotsRefresh = function () {
1863		var _this = this,
1864			c = _this._current,
1865			s = _this.settings;
1866		if ( _this.settings.dots && !_this.$dots ) _this.dotsCreate();
1867		if ( _this.$dots ) {
1868			_this.refreshAddedElements( 'dots' );
1869			if ( s.dots && ( c.dots != s.dots || c.maxActive != c.dotsNumber || c.dotsType != s.dotsType || !_this.$dotsDot ) ) {
1870				/* TODO remove */ //console.log('<<<<< dotsRefresh >>>>> change DOTS');
1871				_this.dotsReplace( s.dotsType );
1872				c.dotsType = s.dotsType;
1873			}
1874		}
1875	};
1876	theinCarousel.prototype.dotsAddEvents = function () {
1877		var _this = this;
1878		if ( _this.$dots ) {
1879			_this.$dots.on( 'click', '.' + _this.prefix + 'dot', function () {
1880				_this.change( $( this ).data( 'item' ) );
1881			});
1882		}
1883	};
1884	/**
1885	 * @create this.$dotsDot
1886	 */
1887	theinCarousel.prototype.dotsReplace = function ( type ) {
1888		var _this = this,
1889			dotsType = type || false,
1890			dotsCounter = 1,
1891			dotsNumber = _this._current.maxActive,
1892			dotsDot = '';
1893
1894		if ( !_this.$dots ) _this.dotsCreate;
1895		while ( dotsCounter <= dotsNumber ) {
1896			dotsDot += '<button class="' + _this.prefix + 'dot" data-item = "' + dotsCounter + '"><span>' + ( dotsType == "number" ? dotsCounter : '' ) + '</span></button>';
1897			dotsCounter++;
1898		}
1899		_this.$dotsDot = $( dotsDot );
1900		_this._current.dotsNumber = dotsNumber;
1901		_this.$dots.toggleClass( _this.prefix + 'dots-number', dotsType == "number" );
1902		_this.$dots.empty().append( _this.$dotsDot );
1903		_this.$dots.toggleClass( _this.cl.disabled, _this._current.maxActive == 1 );
1904		_this.dotsSetActive();
1905	};
1906	theinCarousel.prototype.dotsSetActive = function ( pos ) {
1907		var _this = this,
1908			c = _this._current;
1909		pos = pos || c.active || 1;
1910		pos = pos > c.maxActive ? c.maxActive : pos < 1 ? 1 : pos;
1911		if ( _this.$dotsDot ) {
1912			_this.$dotsDot.removeClass( _this.cl.active );
1913			$( _this.$dotsDot[ pos - 1 ] ).addClass( _this.cl.active );
1914		}
1915	};
1916
1917	/** ---------- COUNTER ---------- */
1918	/**
1919	 * @create this.$counter
1920	 * @create this.$counterOf
1921	 * @create this.$counterSep
1922	 * @create this.$counterMax
1923	 */
1924	theinCarousel.prototype.counterCreate = function () {
1925		var _this = this;
1926		if ( _this.settings.counter ) {
1927			if ( _this.$counter ) _this.$counter.remove();
1928			_this.$counter = $( '<div class="' + _this.prefix + 'counter"></div>' );
1929			_this.$counterOf = $( '<span></span>' );
1930			_this.$counterSep = $( '<i>/</i>' );
1931			_this.$counterMax = $( '<span></span>' );
1932			_this.$counter.append( _this.$counterOf, _this.$counterSep, _this.$counterMax );
1933			_this.counterRefresh();
1934		}
1935	};
1936	theinCarousel.prototype.counterRefresh = function () {
1937		var _this = this;
1938		if ( _this.settings.counter && !_this.$counter ) _this.counterCreate();
1939		if ( _this.$counter ) {
1940			_this.refreshAddedElements( 'counter' );
1941			_this.counterUpdate();
1942		}
1943	};
1944	/**
1945	 * @update this._current.counterSeparator
1946	 */
1947	theinCarousel.prototype.counterUpdate = function () {
1948		var _this = this,
1949			c = _this._current,
1950			s = _this.settings;
1951		if ( _this.$counter ) {
1952			if ( s.counterSeparator != false && c.counterSeparator != s.counterSeparator ) {
1953				c.counterSeparator = s.counterSeparator;
1954				_this.$counterSep.html( c.counterSeparator );
1955			}
1956			if ( _this.$counterOf ) _this.$counterOf.html( c.active );
1957			if ( _this.$counterMax ) _this.$counterMax.html( c.maxActive );
1958			_this.$counter.toggleClass( _this.cl.active, c.maxActive > 1 );
1959			_this.$element.toggleClass( _this.prefix + 'with-counter', c.maxActive > 1 );
1960			_this.$el.toggleClass( _this.prefix + 'with-counter', c.maxActive > 1 );
1961		}
1962	};
1963
1964	/** ---------- NAVIGATE, DOTS, COUNTER - position ---------- */
1965	/**
1966	 * @param {text}
1966 element name ( name = **** )
1967	 * @update this._current.****
1968	 * @update this._current.****Container
1969	 * @update this._current.****Position
1970	 */
1971	theinCarousel.prototype.refreshAddedElements = function ( name ) {
1972		var _this = this,
1973			c = _this._current,
1974			s = _this.settings;
1975		if ( !name ) return false;
1976		var $obj = '$' + name,
1977			container = name + 'Container',
1978			position = name + 'Position';
1979		/* TODO remove */// console.log('element = "'+name+'"', ' (current/settings) ',' view = ('+c[name]+' / '+s[name]+')', ' container = ('+c[container]+' / '+s[container]+')', ' position = '+c[position]+' / '+s[position]+ ')' );
1980		if ( c[ name ] != s[ name ] || c[ container ] != s[ container ] || c[ position ] != s[ position ] ) {
1981			/* TODO remove */ //console.log('<<<<< '+name+' Refresh >>>>>');
1982			if ( c[ name ] && !s[ name ] || c[ name ] && s[ name ] && ( c[ container ] != s[ container ] || c[ position ] != s[ position ] ) ) {
1983				_this[ $obj ].detach();
1984			}
1985			if ( s[ name ] && !c[ name ] || c[ name ] && s[ name ] && ( c[ container ] != s[ container ] || c[ position ] != s[ position ] ) ) {
1986				var place = ( c[ container ] != s[ container ] && $( s[ container ] ) && $( s[ container ] ).length > 0 ) ? $( s[ container ] ) : _this.$el;
1987				if ( s[ position ] == 'before' ) {
1988					place.prepend( _this[ $obj ] );
1989				} else {
1990					place.append( _this[ $obj ] );
1991				}
1992			}
1993			c[ name ] = s[ name ];
1994			c[ container ] = s[ container ];
1995			c[ position ] = s[ position ];
1996		}
1997		_this.setRtl( _this[ $obj ] );
1998	};
1999	theinCarousel.prototype.updateAddedElements = function () {
2000		this.dotsSetActive();
2001		this.navSetActive();
2002		this.counterUpdate();
2003	};
2004
2005	/** MAIN REFRESH */
2006
2007	/**
2008	 * @param   { boolean } min limit.
2009	 * @update  { Object } _this._сurrent
2010	 */
2011	theinCarousel.prototype.refresh = function ( fast ) {
2012
2013		// Обязательно до создания s = _this.settings;
2014		this.getSettings();             // обновляем настройки для разрешения --- @update: s.settings
2015
2016		var _this = this,
2017			c = _this._current,         // текущие значения настроек для данного состояния элементов и размеров, значений больше чем в settings и часть приведена к значениям из %.
2018			s = _this.settings;         // настройки для данного интервала responsive точек
2019
2020		_this.motionRefresh();          // проверяем тип сдвига, обновляем --- @update: c.motionType, c.motionTime
2021
2022		/* TODO REMOVE */ //console.log('★★★★★★★ REFRESH ★★★★★★★ el = ', this.$el, '★★★★★★★ settings = ', this.settings );
2023
2024		_this.checkDeactivate();        // проверка на активность карусели ( скрытие / показ ) --- @update: c.deactivate
2025
2026		_this.itemsUpdate();            // обновляем элементы если селектор элементов изменился - создаются новые итемы карусели
2027
2028		c.itemAutoWidth = s.itemAutoWidth;                          // флаг что ширина элементов зависит от контента
2029
2030		// отступы между элементами ( обязательно рассчитывать каждый раз )
2031		c.between = _this.toPositiveNumber( s.between, _this.$el );
2032		// отступы внутри пака до первого элемента ( обязательно рассчитывать кажыдй раз )
2033		c.outsideLeft = _this.toPositiveNumber( ( s.outsideLeft || s.outsideLeft === 0 ) ? s.outsideLeft : s.outside, _this.$el );
2034		// отступы внутри пака после последнего элемента ( обязательно рассчитывать кажыдй раз )
2035		c.outsideRight = _this.toPositiveNumber( ( s.outsideRight || s.outsideRight === 0) ? s.outsideRight : s.outside, _this.$el );
2036
2037		// сохраняем значения размеров для основных элементов по умолчанию
2038		c.frameWidth = _this.$frame.width() - c.outsideLeft - c.outsideRight;        // ширина фрейма в котором будет двигаться слайдер
2039		c.frameFullWidth = c.frameWidth + c.between;                // ширина фрейма для вычислений включащая отступ для последнего элемента
2040		c.packWidth = c.frameWidth;                                 // ширина пака с итемами
2041		c.packFullWidth = c.frameFullWidth;                         // ширина пака с итемами включая отступ для центрирования и отступ для эластичности на краях
2042		// элементы
2043		c.originLength = _this._origin.length;                      // оригинальное кол-во элементов
2044		c.$itemsOrigin = _this.$itemsOrigin;                        // набор оригинальных итемов слайдера
2045
2046		c.$items = false;                                           // объект всех элементов включая клоны
2047		c.itemsLength = 1;                                          // кол-во элементов включая клоны
2048		c.itemsGridWidth = false;                                   // ширина итема при itemAutoWidth = false;
2049		c.itemsOriginWidth = {};                                    // ширины оригинальных элементов
2050		c.itemsSettings = false;                                    // значения элементов слайдера
2051		// отступы по умолчанию
2052
2053		c.centerShiftBefore = 0;                                    // размер сдвига для центрирования первого элемента
2054		c.centerShiftAfter = 0;                                     // размер сдвига для центрирования последнего элемента
2055
2056		c.elasticShift = 0;                                         // размер для эластичного оттягивания
2057		// настройки поведения
2058		// настройки поведения
2059
2060		c.merge = s.merge;                                          // считывать ширину элементов с дата атрибута data-merge если itemAutoWidth = false
2061		c.rewind = s.rewind;                                        // прокрутка на первый элемент в конце
2062		c.stretch = s.stretch;                                      // элементы тянутся на всю ширину если не заполняют всю ширину
2063		c.sticked = c.motionType == 'scroll' ? false : s.sticked;   // элементы прилипают к краям, при типе сдвига scroll принудительно отключается т.к. доскрол не возможно остановить
2064		c.scaling = s.scaling;                                      // элемент не может быть больше ширины фрейма
2065		c.elasticEnds = s.elasticEnds;                                      // оттягивается в начальной или конечно точках
2066		c.lessCenter = s.lessCenter;                                // центрирование если ширина пака меньше ширины элеменитов
2067		c.center = s.center;                                        // центрирование активного
2068		c.loop = s.loop;                                            // прокрутка по кругу
2069		c.rtl = s.rtl;                                              //
2070		c.slideBy = s.slideBy < 0 ? 1 : Math.min( s.slideBy, c.originLength ); // размер сдвига, не может быть больше кол-ва элементов
2071
2072		// НЕ МЕНЯТЬ ПОРЯДОК !!! т.к. вычисления в последующих методах зависимы от значений вычисляемых ранее
2073
2074		_this.cloneRemove();            // удаляем клоны и очищаем значения свойст свзяанных с клонами
2075		_this.setRtl();                 // выставляем / удаляем класс на элемент rtl и сохраняем новое значение c.rtl
2076
2077		_this.getItemsOriginWidth();    // обновляем оъект оригинальных ширин для рассчетов
2078		_this.cloneRefresh();           // обновляем клоны, вставляем в вверстку и обновляем объекты клонов
2079		_this.getElasticShift();        // вычисляем ширину области для эластичного сдвига на краях - !!!обязательно до getItemsSetting!!! т.к. участвует в расчетах
2080		_this.getItemsSetting();        // получаем объект со свойствами элементов для расчетов
2081		_this.getCenterShifts();        // вычисляем добавку отступов снаружи для центрирования
2082		_this.getPackWidth();           // вычисление ширины пака
2083		_this.getPackFullWidth();       // общая ширина пака для вычислений
2084
2085		// выставляем размеры эелментов
2086		_this.setItemsBetween();        // Устанавливаем отступы между элементами
2087		_this.setItemsWidth();          // Устанавливаем ширины элементам
2088		_this.setPackIndents();         // изменяем отступы снаружи элементов + сдвиг центрирования + сдвиг для эластичности на краях
2089		_this.setPackWidth();           // Выставляем ширину $pack
2090
2091		// разница для определения
2092		c.difference = c.frameWidth - c.packWidth;
2093
2094		_this.updateMaxActive();
2095		_this.updateLimits();           // после updateMaxActive
2096
2097		/* TODO REMOVE */ //console.log( ' rtl = '+c.rtl+ ' | maxActive = '+c.maxActive+' | c.limitMin = '+c.limitMin+' | c.limitMax = '+ c.limitMax+' | $el = ', this.$el);
2098
2099		if ( c.active > c.maxActive ) {
2100			c.active = c.maxActive;
2101			_this.counterUpdate();
2102		}
2103
2104		// сдвигаем на активный элемент без анимации
2105		_this.change( c.active, true );
2106		_this.updateAddedElements();
2107
2108		/* TODO REMOVE */ //console.log( '=== After refresh === ', c );
2109
2110	};
2111
2112	/** Обновление значений наборов итемов */
2113	theinCarousel.prototype.getItemsObject = function() {
2114		this._current.$items = $('.' + this.prefix + 'item', this.$pack );
2115		this._current.itemsLength = this._current.$items.length;
2116	};
2117	/** Выставление / удаление класса rtl */
2118	theinCarousel.prototype.setRtl = function( $obj ) {
2119		var c = this._current,
2120			$obj =  typeof $obj == 'object' ? $obj : this.$el;
2121		$obj.toggleClass( this.prefix + 'rtl', c.rtl );
2122		return c.rtl ? true : false;
2123	};
2124	/**
2125	 * Получение объекта ширин оригинальных элементов
2126	 * @update this._current.itemsOriginWidth
2127	 */
2128	theinCarousel.prototype.getItemsOriginWidth = function () {
2129		var _this = this,
2130			c = _this._current,
2131			s = _this.settings;
2132
2133		c.itemsGridWidth = false; // обнуляем ширину итема по сетке
2134
2135		if ( c.itemAutoWidth == true){
2136			/** делаем пак большого размера и размери элементов авто чтобы элементы стали реального размера */
2137			_this.$pack.width( 100000000 );
2138			_this.$itemsOrigin.width( 'auto' );
2139		} else {
2140			/** вычисление размера ячейки для сетки */
2141			var _choose = {
2142				items: s.items > 0 ? s.items : 1,
2143				itemWidth: _this.toPositiveNumber( s.itemWidth, _this.$el ),
2144				itemMinWidth: _this.toPositiveNumber( s.itemMinWidth, _this.$el )
2145			};
2146			if ( _choose.itemMinWidth > 0 ) {
2147				var visible = Math.floor( c.frameFullWidth / ( _choose.itemMinWidth + c.between ) ) || 1;
2148				c.itemsGridWidth = ( c.frameFullWidth / Math.min( visible, c.originLength ) ) - c.between;
2149			} else if ( _choose.itemWidth > 0 ) {
2150				c.itemsGridWidth = _choose.itemWidth;
2151			} else if ( _choose.items > 0 ) {
2152				c.itemsGridWidth = ( c.frameFullWidth / _choose.items - c.between );
2153			}
2154			if ( c.stretch && c.frameFullWidth > ( ( c.itemsGridWidth + c.between ) * c.originLength ) ) {
2155				c.itemsGridWidth = ( c.frameFullWidth / c.originLength ) - c.between;
2156			}
2157			/* TODO REMOVE */ //console.log('...... c.itemsGridWidth = '+ c.itemsGridWidth);
2158		};
2159
2160		c.itemsOriginWidth = {};
2161
2162		var _fullWidth = 0,
2163			_stretchWidth = 0,
2164			_noStretchWidth = 0;
2165		$.each( _this.$itemsOrigin, function( i, el ){
2166			var merge = $( el ).data( 'merge' ),
2167				noStretch = $( el ).data( 'no-stretch' ),
2168				width = c.itemsGridWidth ? ( merge > 0 ? ( ( parseInt( merge ) * ( c.itemsGridWidth + c.between ) ) - c.between ) : c.itemsGridWidth ) : $(el).width(); // тут в конце было  el.getBoundingClientRect().width
2169			/* TODO REMOVE */ //console.log( '--- itemsOriginWidth ', ( i + 1 ),' - width = ', width ,' frameWidth = ', c.frameWidth );
2170			c.itemsOriginWidth[ i + 1 ] = ( c.scaling && width > c.frameWidth ) ? c.frameWidth : width;
2171			_fullWidth += c.itemsOriginWidth[ i + 1 ] + c.between;
2172			if ( noStretch ) {
2173				_noStretchWidth += c.itemsOriginWidth[ i + 1 ] + c.between;
2174			} else {
2175				_stretchWidth += c.itemsOriginWidth[ i + 1 ] + c.between;
2176			}
2177		});
2178
2179		/* TODO REMOVE */ //console.log('c.frameFullWidth = ' + c.frameFullWidth + ' noStretchWidth = ' + _noStretchWidth + ' stretchWidth = '+_stretchWidth);
2180		/* TODO REMOVE */ //console.log('stretch = '+c.stretch+' itemAutoWidth = '+c.itemAutoWidth);
2181
2182		// пересчет размеров элементов для авто ширины с учетом атрибута no-stretch
2183		if ( c.itemAutoWidth && c.stretch && c.frameFullWidth > _fullWidth && _stretchWidth > 0 ){
2184			_fullWidth = 0;
2185			$.each( _this.$itemsOrigin, function( i, el ){
2186				var noStretch = $( el ).data( 'no-stretch' );
2187				if ( !noStretch ) {
2188					c.itemsOriginWidth[ i + 1 ] = ( ( ( c.itemsOriginWidth[ i + 1 ] + c.between ) * 100 / _stretchWidth ) / 100 * ( c.frameFullWidth - _noStretchWidth ) ) - c.between;
2189					/* TODO REMOVE */ //c.itemsOriginWidth[ i + 1 ] = parseInt( c.itemsOriginWidth[ i + 1 ]*100 - 1)/100;
2190				}
2191				/* TODO REMOVE */ //console.log( 'element '+(i + 1)+' = ' +c.itemsOriginWidth[ i + 1 ] +' fix = ' + (parseInt( c.itemsOriginWidth[ i + 1 ]*100 - 1)/100) );
2192				_fullWidth += c.itemsOriginWidth[ i + 1 ] + c.between;
2193			});
2194		}
2195
2196		c.itemsOriginWidth.fullWidth = _fullWidth;
2197		c.itemsOriginWidth.width = _fullWidth - c.between;
2198		c.itemsOriginWidth.between = c.between;
2199
2200		if ( c.itemAutoWidth == true ) _this.$pack.width( 'auto' );
2201
2202		_this.getItemsObject();
2203		/* TODO REMOVE */ //console.log( '---------- itemsOriginWidth ----------', c.itemsOriginWidth, _this.$el );
2204
2205	};
2206	/**
2207	 * Получение ширины элемента по сетке
2208	 * @update this._current.itemsGridWidth;
2209	 */
2210	theinCarousel.prototype.getItemGridWidth = function(){
2211		var _this = this,
2212			c = _this._current,
2213			s = _this.settings;
2214		c.itemsGridWidth = false;
2215		// Если щирина не авто вычисляем ширину для сетки
2216		if ( c.itemAutoWidth !== true ) {
2217			var _choose = {
2218				items: s.items > 0 ? s.items : 1,
2219				itemWidth: _this.toPositiveNumber( s.itemWidth, _this.$el ),
2220				itemMinWidth: _this.toPositiveNumber( s.itemMinWidth, _this.$el )
2221			};
2222			if ( _choose.itemMinWidth > 0 ) {
2223				var visible = Math.floor( c.frameFullWidth / ( _choose.itemMinWidth + c.between ) ) || 1;
2224				c.itemsGridWidth = ( c.frameFullWidth / Math.min( visible, c.originLength ) ) - c.between;
2225			} else if ( _choose.itemWidth > 0 ) {
2226				c.itemsGridWidth = _choose.itemWidth;
2227			} else if ( _choose.items > 0 ) {
2228				c.itemsGridWidth = ( c.frameFullWidth / _choose.items - c.between );
2229			}
2230			if ( c.stretch && c.frameFullWidth > ( ( c.itemsGridWidth + c.between ) * c.originLength ) ) {
2231				c.itemsGridWidth = ( c.frameFullWidth / c.originLength ) - c.between;
2232			}
2233			/* TODO REMOVE */ //console.log('...... c.itemsGridWidth = '+ c.itemsGridWidth);
2234		}
2235		/* TODO REMOVE */ //console.log( '---------- itemsGridWidth ------------', c.itemsGridWidth );
2236		return c.itemsGridWidth;
2237	};
2238	/**
2239	 * @update this._current.visibleItems
2240	 * @update this._current.itemsGridWidth
2241	 * */
2242	theinCarousel.prototype.getItemsSetting = function () {
2243		var _this = this,
2244			c = _this._current,
2245			counter = 1 - c.cloneBeforeLength;
2246
2247		c.itemsSettings = {}; // объект размеров для итемов
2248
2249		if ( c.$items && c.$items.length > 0 ){
2250			$.each( c.$items, function( i, el ){
2251				var number = $( el ).data( 'item' ),
2252					prew = c.itemsSettings[ ( counter - 1 ) ],
2253					width = c.itemsOriginWidth[ number ],
2254					shift = ( prew ? ( prew.shift + c.between + ( c.center ? ( ( prew.width + width ) / 2 ) : ( prew.width ) ) ) : c.elasticShift );
2255				c.itemsSettings[ counter ] = {
2256					item: number,
2257					width: width,
2258					shift: ( c.motionType == 'scroll' ? Math.round( shift ) : shift ), // особенность Scroll не понимает дробные части и двигается только по целым
2259					$el: $( el )
2260				};
2261				counter++;
2262			});
2263			counter--;
2264			c.itemsSettings.width = c.itemsSettings[ counter ].shift + c.itemsSettings[ counter ].width;
2265			c.itemsSettings.fullWidth = c.itemsSettings.width + c.between;
2266			c.itemsSettings.first = 1 - c.cloneBeforeLength;
2267			c.itemsSettings.last = counter;
2268		}
2269		/* TODO REMOVE */ //console.log( '  ' );
2270		/* TODO REMOVE */ //console.log( '✴✴✴✴✴ itemsSettings ✴✴✴✴✴ ', c.itemsSettings );
2271		/* TODO REMOVE */ //console.log( '  ' );
2272	};
2273	/** Установка ширин элементов */
2274	theinCarousel.prototype.setItemsWidth = function () {
2275		var _this = this,
2276			c = this._current;
2277		if ( c.itemsOriginWidth ){
2278			$.each( c.itemsOriginWidth, function( i, v ){
2279				$('.' + _this.prefix + 'item[data-item=' + i + ']', _this.$pack ).width( v );
2280			});
2281		}
2282	};
2283	/** Получение величины для эластичного сдвинга */
2284	theinCarousel.prototype.getElasticShift = function () {
2285		var c = this._current;
2286		c.elasticShift = ( c.elasticEnds && !c.loop && c.motionType != 'scroll' ) ? c.frameWidth * 0.9 : 0;
2287	};
2288	/** Вычисление отступов для центрирования элемента */
2289	theinCarousel.prototype.getCenterShifts = function () {
2290		var c = this._current;
2291		if ( c.center && c.itemsSettings ){
2292			c.centerShiftBefore = ( c.frameWidth - c.itemsSettings[ c.itemsSettings.first ].width ) / 2;
2293			c.centerShiftAfter = ( c.frameWidth - c.itemsSettings[ c.itemsSettings.last ].width ) / 2;
2294		}
2295	};
2296	/** Вычисление ширины набора элементов */
2297	theinCarousel.prototype.getPackWidth = function () {
2298		var c = this._current,
2299			packWidth = 0;
2300		if ( c.$items ){
2301			$.each( c.$items, function( i, el ){
2302				packWidth += ( c.itemsOriginWidth[ $( el ).data( 'item' ) ]  + c.between );
2303			});
2304			c.packWidth = packWidth - c.between;
2305		}
2306		/* TODO REMOVE */ //console.log( '=== c.packWidth = '+c.packWidth);
2307		return c.packWidth;
2308	};
2309	theinCarousel.prototype.getPackFullWidth = function () {
2310		var c = this._current;
2311		c.packFullWidth = c.packWidth + c.between + c.centerShiftBefore + c.centerShiftAfter + ( c.elasticShift * 2 );
2312		return c.packFullWidth;
2313	}
2314	/** выставление отступов между элементами */
2315	theinCarousel.prototype.setItemsBetween = function () {
2316		var c = this._current;
2317		c.$items.filter(':not(:last-child)').css({
2318			'margin-left': c.rtl ? c.between : '',
2319			'margin-right': c.rtl ? '' : c.between
2320		});
2321		c.$items.filter(':last-child').css({
2322			'margin-left': c.rtl ? '-1px' : '',  // -1px что бы последний элемент не падал со строчки при не правльном высислении
2323			'margin-right': c.rtl ? '' : '-1px'
2324		});
2325	};
2326	/** Установка внешних отступов у набора */
2327	theinCarousel.prototype.setPackIndents = function () {
2328		var c = this._current;
2329		this.$pack.css({
2330			'padding-left': c.outsideLeft + ( c.rtl ? c.centerShiftAfter : c.centerShiftBefore ) + c.elasticShift,
2331			'padding-right': c.outsideRight + ( c.rtl ? c.centerShiftBefore : c.centerShiftAfter ) + c.elasticShift
2332		});
2333	};
2334	/** Yстанвока ширины на набор элементов */
2335	theinCarousel.prototype.setPackWidth = function () {
2336		this.$pack.width( this._current.packWidth );
2337	};
2338	/** Удаление клонов если есть
2339	 * @update this._current.$clone
2340	 * @update this._current.cloneBeforeLength
2341	 * @update this._current.cloneBeforeWidth
2342	 * @update this._current.cloneAfterLength
2343	 * @update this._current.cloneAfterWidth
2344	 */
2345	theinCarousel.prototype.cloneRemove = function(){
2346		var c = this._current;
2347		if ( c.$clone ){
2348			c.$clone.remove();
2349		}
2350		c.$clone = false;
2351		c.cloneBeforeLength = 0;
2352		c.cloneBeforeWidth = 0;
2353		c.cloneAfterLength = 0;
2354		c.cloneAfterWidth = 0;
2355	};
2356
2357	/** Пересоздание клонов в зависимости от ширины */
2358	theinCarousel.prototype.cloneRefresh = function(){
2359		var _this = this,
2360			c = this._current;
2361		if ( c.$clone ) _this.cloneRemove();
2362		if ( c.loop ) {
2363			var counterBefore = c.originLength,
2364				counterAfter = 1,
2365				minClone = Math.max( c.slideBy, 2 ),
2366				minWidthBefore = c.center ? ( c.frameWidth / 2 ) : 0,
2367				minWidthAfter = c.center ? ( c.frameWidth / 2 ) : c.frameWidth;
2368			/* TODO delete */  //console.log('minClone = '+minClone+' --- minWidthBefore = '+minWidthBefore+' --- minWidthAfter = '+minWidthAfter);
2369
2370			// добавляем клоны "до" для корректной прокрутки по slideBy
2371			while ( c.cloneBeforeLength < minClone ) {
2372				_this.cloneAdd( ( counterBefore - 1 ), true );
2373				c.cloneBeforeLength++;
2374				counterBefore = ( counterBefore - 1 ) > 0 ? ( counterBefore - 1 ) : c.originLength;
2375				/* TODO delete */ //console.log(' c.cloneBeforeWidth = '+c.cloneBeforeWidth+' minWidthBefore = '+minWidthBefore+' c.cloneBeforeLength = '+c.cloneBeforeLength+' c.slideBy = '+c.slideBy);
2376			};
2377			// добавляем клоны "до" по ширине для компенсации сдвига
2378			while ( c.cloneBeforeWidth < minWidthBefore  ) {
2379				_this.cloneAdd( ( counterBefore - 1 ), true );
2380				c.cloneBeforeLength++;
2381				c.cloneBeforeWidth += ( c.itemsOriginWidth[ counterBefore ] + c.between );
2382				counterBefore = ( counterBefore - 1 ) > 0 ? ( counterBefore - 1 ) : c.originLength;
2383				/* TODO delete */ //console.log(' c.cloneBeforeWidth = '+c.cloneBeforeWidth+' minWidthBefore = '+minWidthBefore+' c.cloneBeforeLength = '+c.cloneBeforeLength+' c.slideBy = '+c.slideBy);
2384			};
2385
2386			// добавляем клоны "после" для корректной прокрутки по slideBy
2387			while ( c.cloneAfterLength < minClone ) {
2388				_this.cloneAdd( ( counterAfter - 1 ) );
2389				c.cloneAfterLength++;
2390				counterAfter = ( counterAfter + 1 ) <= c.originLength ? ( counterAfter + 1 ) : 1;
2391				/* TODO delete */ //console.log(' c.cloneAfterWidth = '+c.cloneAfterWidth+' minWidthAfter = '+minWidthAfter+' c.cloneAfterLength = '+c.cloneAfterLength+' c.slideBy = '+c.slideBy);
2392			};
2393			// добавляем клоны "после" по ширине для компенсации сдвига
2394			while ( c.cloneAfterWidth < minWidthAfter  ) {
2395				_this.cloneAdd( ( counterAfter - 1 ) );
2396				c.cloneAfterLength++;
2397				c.cloneAfterWidth += ( c.itemsOriginWidth[ counterAfter ] + c.between );
2398				counterAfter = ( counterAfter + 1 ) <= c.originLength ? ( counterAfter + 1 ) : 1;
2399				/* TODO delete */ //console.log(' c.cloneAfterWidth = '+c.cloneAfterWidth+' minWidthAfter = '+minWidthAfter+' c.cloneAfterLength = '+c.cloneAfterLength+' c.slideBy = '+c.slideBy);
2400			};
2401
2402			c.$clone = $( '.' + this.cl.main + '__item.' + this.cl.clone , _this.$pack );
2403			_this.getItemsObject();
2404		}
2405	};
2406	theinCarousel.prototype.cloneAdd = function( counter, position ){
2407		var _this = this,
2408			c = this._current;
2409		var $clone = $( c.$itemsOrigin[ counter ] ).clone( true ).addClass( _this.cl.clone );
2410		if ( position == 'prepend' || position === true ) {
2411			_this.$pack.prepend( $clone );
2412		} else {
2413			_this.$pack.append( $clone );
2414		}
2415	};
2416	theinCarousel.prototype.updateMaxActive = function () {
2417		var _this = this,
2418			c = _this._current;
2419		c.maxActive = _this._origin.length ;
2420		if ( !c.loop && !c.center && c.dots != 'each' && c.originLength >= 1 ) {
2421			var counter = c.originLength,
2422				itemsWidth = c.itemsSettings[ counter ].width;
2423			/* TODO REMOVE */ //console.log( ' itemsWidth = '+itemsWidth+'   c.frameWidth = '+ c.frameWidth+' counter - 1 = '+( counter - 1 ) );
2424
2425			while ( itemsWidth <= ( c.frameWidth + 1 ) && ( counter - 1 ) >= 1 && counter-- ){
2426				itemsWidth += ( c.itemsSettings[ counter ].width + c.between );
2427				if ( itemsWidth <= ( c.frameWidth + 1 ) ) c.maxActive--;
2428				/* TODO REMOVE */ //console.log( ' itemsWidth = '+itemsWidth+'  c.frameWidth = '+ c.frameWidth+' counter - 1 = '+( counter - 1 )+'c.maxActive = '+c.maxActive);
2429			}
2430		}
2431		/* TODO REMOVE */ //console.log( ' c.maxActive = '+c.maxActive );
2432		return c.maxActive;
2433	};
2434	/** Вычисление минимальной и максимальной координат сдвига  */
2435	theinCarousel.prototype.updateLimits = function () {
2436		var c = this._current,
2437			min = this.calculateShiftPosition( 1 ),
2438			max = this.calculateShiftPosition( c.maxActive );
2439		if ( c.maxActive == 1 && !c.loop && !c.center && c.frameWidth < c.packWidth ){
2440			max = this.calculateShift( ( c.rtl ? 1 : -1 ) * ( c.itemsSettings[ 1 ].shift + c.itemsSettings[ 1 ].width ) );
2441		}
2442		c.limitMin = c.motionType == 'scroll' ? ( c.rtl ? max : min ) : ( c.rtl ? min : max ) ;
2443		c.limitMax = c.motionType == 'scroll' ? ( c.rtl ? min : max ) : ( c.rtl ? max : min ) ;
2444		/* TODO REMOVE */ //console.log( ' rtl = '+c.rtl+ ' | maxActive = '+c.maxActive+' | c.limitMin = '+c.limitMin+' | c.limitMax = '+ c.limitMax+' | $el = ', this.$el);
2445	};
2446
2447
2448	/** ------ NAVIGATE ----- */
2449	/** Следующие элемент */
2450	theinCarousel.prototype.prev = function ( duration ) {
2451		this.nearby( 'prev', duration );
2452	};
2453	/** Предыдущий элемент */
2454	theinCarousel.prototype.next = function ( duration ) {
2455		this.nearby( 'next', duration );
2456	};
2457	/** Соседний ( следующие / предыдущий ) элемент */
2458	theinCarousel.prototype.nearby = function ( direction, slideBy, duration ) {
2459		if ( direction != 'prev' && direction != 'next' ) return false;
2460		var _this = this,
2461			c = _this._current,
2462			position = c.activePosition + ( direction == 'prev' ? -1 : 1 ) * ( slideBy ? slideBy : c.slideBy );
2463		/* TODO REMOVE */ //console.log('=== NEARBY === | loop '+(c.loop?'✔':'X')+' | rewind '+(c.rewind?'✔':'X')+' | direction = '+direction+' | position = '+position+' | maxActive = '+c.maxActive+ ' | c.active = '+ c.active+ ' | c.activePosition = '+ c.activePosition+' | slideBy = '+c.slideBy );
2464		if ( c.loop == true || c.rewind == true || ( direction == 'prev' && c.active > 1 ) || ( direction == 'next' && c.active < c.maxActive ) ) {
2465			_this.enterState( direction );
2466			_this.setTrigger( direction );
2467			_this.change( position, duration );
2468			setTimeout( function () {
2469				_this.leaveState( direction );
2470			}, _this.calcDuration( duration ) );
2471		}
2472	};
2473	/** Смена элемента */
2474	theinCarousel.prototype.change = function ( position, duration ) {
2475		var _this = this,
2476			c = _this._current;
2477
2478		/* TODO REMOVE */ //console.log('=== CHANGE === enter data === position = '+position+' | duration = '+duration+' | loop = '+ (c.loop?'✔':'X') + ' | rewind = '+ (c.rewind?'✔':'X') +' | maxActive = '+c.maxActive);
2479
2480		if ( !position && position != 0 ) return false;
2481
2482		_this.enterState( 'change' );
2483		_this.setTrigger( 'change' );
2484		duration = _this.calcDuration( duration );
2485
2486		var toPosition = position;
2487
2488		if ( ( c.loop == true || c.rewind == true ) && ( position < 1 || position > c.maxActive ) ) {
2489
2490			var toPosition = position <= 0 ? ( c.maxActive + position ) : ( position - c.maxActive ),
2491				looping = ( c.loop == true && !_this.isState( 'drag' ) ) ? true : false,
2492				dalayTimeout = looping ? 10 : 0;
2493			if ( looping ) {
2494				var loopingPosition = _this.calculateShiftPosition( c.active + ( position <= 0 ? 1 : -1 ) * c.maxActive );
2495				_this.setPackShift( loopingPosition, true );
2496			}
2497			setTimeout( function () {
2498				_this.setPackShift( _this.calculateShiftPosition( toPosition ), duration - dalayTimeout );
2499			}, dalayTimeout );
2500		} else {
2501			toPosition = position < 1 ? 1 : position > c.maxActive ? c.maxActive : position;
2502			_this.setPackShift( _this.calculateShiftPosition( toPosition ), duration );
2503		}
2504		c.activePosition = toPosition;
2505		_this.getRealActive();
2506		if ( c.motionType != 'scroll' ) _this.updateAddedElements();
2507		// по окончанию сдвига выставляем класс на новый активный элемент
2508		setTimeout( function () {
2509			/* TODO REMOVE */ //console.log( ' === CHANGE === c.active = '+c.active+' c.activePosition='+c.activePosition);
2510			_this.toRealActive();
2511			_this.setActive( c.active );
2512			_this.leaveState( 'change' );
2513			_this.setTrigger( 'changed' );
2514			/* TODO REMOVE */ //console.log('=== after CHANGE === c.active = '+c.active+' c.activePosition='+c.activePosition);
2515		}, duration );
2516	};
2517
2518	/**
2519	 * Вычисление длительности на основе переданного значения
2520	 * @param { boolean | number } duration
2521	 * @return { number } normalize duration
2522	 * */
2523	theinCarousel.prototype.calcDuration = function ( duration ) {
2524		return duration === true ? 0 : ( duration >= 0 && duration !== false ) ? duration : ( this._current.motionTime || 0 );
2525	};
2526	/**
2527	 * Установка класса на активный элемент в полосе или снятие метки активного элемента если номер не передан
2528	 * @param { none | number } active position
2529	 * */
2530	theinCarousel.prototype.setActive = function ( position ) {
2531		var _this = this,
2532			c = _this._current;
2533		c.$items.removeClass( _this.cl.active );
2534		if ( c.itemsSettings[ position ] ) {
2535			c.itemsSettings[ position ].$el.addClass( _this.cl.active );
2536		}
2537	};
2538	/** Вычисление сдвига линии по позиции */
2539	theinCarousel.prototype.calculateShiftPosition = function ( position ) {
2540		if ( !this._current.itemsSettings[ position ] ) return false;
2541		return( this.calculateShift( ( this._current.rtl ? 1 : -1 ) * this._current.itemsSettings[ position ].shift ) );
2542	};
2543
2544	theinCarousel.prototype.calculateShift = function ( shift ) {
2545		if ( !shift && shift != 0 ) return false;
2546		var _this = this,
2547			c = _this._current,
2548			sign = c.rtl ? 1 : -1;
2549		/* TODO REMOVE */ //console.log( '=== Получение сдвига === position = '+ position + ' shift = '+ shift +' frameFull = '+c.frameWidth+' packWidth = '+c.packWidth+' elastic = '+c.elasticShift );
2550		// проверка координаты чтобы при прокрутке к последнему элементу он был в противоположный край и после него не было места
2551		_this.$pack.css( { 'margin-left': 0, 'margin-right': 0 } );
2552		if ( !c.loop && !c.center ){
2553			if ( c.frameWidth > c.packWidth ){
2554				if ( c.lessCenter ){
2555					if (  c.motionType == 'scroll' ){
2556						_this.$pack.css( c.rtl ? 'margin-right' : 'margin-left', ( ( c.frameWidth - c.packWidth ) / 2 ) );
2557					} else {
2558						shift = shift - sign * ( c.frameWidth - c.packWidth ) / 2;
2559					}
2560				} else {
2561					shift = sign * c.itemsSettings[ 1 ].shift;
2562				}
2563				/* TODO REMOVE */ //console.log( '=== Пересчет FRAME > PACK = '+ shift);
2564			} else {
2565				if ( ( sign * shift + c.frameFullWidth ) > ( c.packFullWidth - c.elasticShift ) ) {
2566					shift = sign * ( c.packFullWidth - c.elasticShift - c.frameFullWidth );
2567					/* TODO REMOVE */ //console.log( '=== Пересчет сдвига CHANGED MAX = '+ shift);
2568				}
2569			}
2570		}
2571		// пересчет для scroll с rtl
2572		shift = _this.calculateShiftMotionScroll( shift );
2573		return shift;
2574	};
2575
2576	/** Пересчет позиции для типа сдвига scroll  */
2577	theinCarousel.prototype.calculateShiftMotionScroll = function ( shift ) {
2578		var c = this._current;
2579		if ( c.motionType == 'scroll' ) {
2580			shift = c.rtl ? ( c.packFullWidth - c.frameFullWidth - shift ) : ( Math.abs( shift ) );
2581			/* TODO REMOVE */ //console.log( '=== Пересчет для SCROLL = '+shift);
2582		}
2583		return shift;
2584	};
2585
2586	/** PACK SHIFT */
2587	/**
2588	 * Установка сдвига полосы с элементами
2589	 * @param { number } shift size
2590	 * @param { boolean | number } time
2591	 * */
2592	theinCarousel.prototype.setPackShift = function ( shift, duration ) {
2593		if ( !shift && shift != 0 ) return false;
2594		var _this = this,
2595			c = _this._current;
2596		/* TODO REMOVE */ //console.log(' === setPackShift ===  motionType='+c.motionType+' shift='+shift+' active = '+c.active+' activePosition = '+c.activePosition);
2597		if ( shift === false ) return false;
2598		duration = _this.calcDuration( duration );
2599		if ( c.motionType == 'scroll' ) {
2600			_this.$frame.stop().animate({
2601				scrollLeft: Math.round( shift )     // округляем до ближайшего целого при позиционировании в скролле
2602			}, duration );
2603		} else if ( c.motionType == 'transform' ) {
2604			_this.setStyle( _this.$pack, {
2605				transition: duration === 0 ? 'none' : { duration: duration },
2606				transform: 'translate3d(' + shift + 'px, 0px, 0px)'
2607			});
2608		} else if ( c.motionType == 'animate' ) {
2609			_this.$pack.stop().animate({
2610				left: shift
2611			}, duration );
2612		} else {
2613			return false;
2614		}
2615	};
2616	/**
2617	 * Получение значения прокрутки полосы с элементами
2618	 * @return {boolean | number} coordinate
2619	 * */
2620	theinCarousel.prototype.getPackShift = function () {
2621		var _this = this,
2622			c = _this._current,
2623			coordinate;
2624		if ( c.motionType == 'scroll' ) {
2625			coordinate = {
2626				x: _this.$frame.scrollLeft(),
2627				y: _this.$frame.scrollTop()
2628			}
2629		} else if ( c.motionType == 'transform' ) {
2630			coordinate = _this.$pack.css( 'transform' ).replace(/.*\(|\)| /g, '').split(',');
2631			coordinate = {
2632				x: +( coordinate[ 0 ] == 'none' ? 0 : coordinate[ coordinate.length === 16 ? 12 : 4 ] ),
2633				y: +( coordinate[ 0 ] == 'none' ? 0 : coordinate[ coordinate.length === 16 ? 13 : 5 ] )
2634			};
2635		} else {
2636			coordinate = {
2637				x: parseInt( _this.$pack.css( 'left' ) ),
2638				y: parseInt( _this.$pack.css( 'top' ) )
2639			};
2640		}
2641		return coordinate !== undefined ? coordinate : false;
2642	};
2643	/**
2644	 * Останавливаем прокрутку полосы с элементами
2645	 * */
2646	theinCarousel.prototype.stopPackShift = function () {
2647		var _this = this,
2648			c = _this._current;
2649		/* TODO REMOVE */ //console.log(' === stopPackShift ===');
2650		if ( c.motionType == 'scroll' ) {
2651			_this.$frame.stop();
2652			window.clearTimeout(_this.scrollTimer);
2653			if ( _this.isState( 'scrolling' ) ) _this.leaveState('scrolling');
2654		} else if ( c.motionType == 'transform' ) {
2655			_this.setStyle(_this.$pack, {
2656				transition: 'none',
2657				transform: 'translate3d(' + _this.getPackShift().x + 'px, 0px, 0px)'
2658			})
2659		} else if ( c.motionType == 'animate' ) {
2660			_this.$pack.stop();
2661		} else {
2662			return false;
2663		}
2664	};
2665
2666	/** DEACTIVATE */
2667	theinCarousel.prototype.checkDeactivate = function () {
2668		var _this = this,
2669			c = _this._current,
2670			s = _this.settings;
2671		if ( s.deactivate != c.deactivate ) {
2672			if ( s.deactivate == true ) {
2673				this.deactivate();
2674			} else {
2675				this.activate();
2676			}
2677			c.deactivate = s.deactivate
2678		}
2679		return c.deactivate;
2680	};
2681	theinCarousel.prototype.deactivate = function () {
2682		if ( this.$el && this.$element ) {
2683			this.$el.detach();
2684			this.$element.append( this._origin.$html  );
2685		}
2686	};
2687	theinCarousel.prototype.activate = function () {
2688		if ( this.$el && this.$element ) {
2689			this._origin.$html .detach();
2690			this.$element.append( this.$el );
2691		}
2692	};
2693
2694	/** DESTROY */
2695	theinCarousel.prototype.destroy = function () {
2696		/* TODO remove Дописать позже */
2697		console.log('DESTROY');
2698	};
2699
2700	/** UPDATE */
2701	theinCarousel.prototype.update = function ( options ) {
2702		/* TODO remove */ //console.log('^ ^ ^ ^ ^ ^ update options ');
2703		this.userOptions = $.extend(true, {}, this.userOptions, options );
2704		this.options = $.extend( true, {}, this.options, this.userOptions );
2705	};
2706
2707	/** DRAG */
2708	/** добавление эвентов для перетаскивания */
2709	theinCarousel.prototype.dragRegisterEvents = function () {
2710		var _this = this;
2711		_this.$pack.on( "touchstart." + _this.pluginNumber + "  mousedown." + _this.pluginNumber, function ( e ) {
2712			if ( e.type == "touchstart" || ( e.type == "mousedown" && e.button == 0 )) {
2713				_this.stopPackShift();
2714				_this.dragStart( e );
2715			}
2716		});
2717		$( window ).on( "touchend." + _this.pluginNumber + "  mouseup." + _this.pluginNumber, function ( e ) {
2718			if ( e.type == "touchend" || ( e.type == "mouseup" && e.button == 0 ) ) _this.dragEnd();
2719		});
2720	};
2721	/** bind drag events and data recording */
2722	theinCarousel.prototype.dragStart = function ( e ) {
2723		var _this = this,
2724			c = _this._current,
2725			d = c._drag;
2726		if ( e.type == "touchstart" ) {
2727			_this.enterState('touch');
2728		}
2729		if ( e.type == "mousedown" ) {
2730			_this.enterState('grab');
2731			e.preventDefault();
2732			e.stopPropagation();
2733		}
2734		d.itemStart = c.activePosition;
2735		d.timeStart = $.now();
2736		d.touchStart = _this.getEventCoord( e );
2737		d.shiftStart = _this.getPackShift();
2738		d.delta = 0;
2739		d.checkDirection = false;
2740		_this.$pack.addClass(_this.prefix + 'grab'); // добавляем на пак класс захвата
2741		if ( e.type == 'touchstart' ) {
2742			$( window ).bind( "touchmove." + _this.pluginNumber, _this, _this.dragMove );
2743		} else if ( e.type == 'mousedown' ) {
2744			$( window ).bind( "mousemove." + _this.pluginNumber, _this, _this.dragMove );
2745		}
2746	};
2747	/** unbind drag events */
2748	theinCarousel.prototype.dragEnd = function () {
2749		var _this = this,
2750			c = _this._current,
2751			d = c._drag,
2752			deltaSize = 3,          // размер сдвига при котором начинается сдвиг
2753			delayTime = 300;        // время прошедшее сначала захвата при котором начинается сдвиг
2754
2755		if ( _this.isState( 'touch' ) ) _this.leaveState( 'touch' );
2756		if ( _this.isState( 'grab') ) _this.leaveState( 'grab' );
2757		// отписываемся от событий move
2758		$( window ).unbind( "touchmove." + _this.pluginNumber + " mousemove." + _this.pluginNumber );
2759		_this.$pack.removeClass( _this.prefix + 'grab' );
2760		// если слайдер был сдвинут
2761		if ( _this.isState('drag') ) {
2762			// Отключаем событие клик если слайдер был сдвинут на более чем 3px или прошло более 300ms
2763			if ( Math.abs( d.delta ) > deltaSize || new Date().getTime() - d.timeStart > delayTime ) {
2764				_this.$frame.find( '*' ).one( "click.in" + _this.cl.main, function () {
2765					return false;
2766				});
2767				setTimeout( function () {
2768					_this.$frame.find( '*' ).unbind( "click.in" + _this.cl.main);
2769				}, 100 );
2770			}
2771			if ( c.sticked ) {
2772				/* TODO REMOVE */ //console.log( '=== dragEnd ===  d.itemStart = '+d.itemStart+' c.active = '+ c.active+' d.delta = '+d.delta+' deltaSize = '+deltaSize+' c.active = '+c.active+' c.activePosition = '+c.activePosition );
2773				if ( d.itemStart == c.active && Math.abs( d.delta ) > deltaSize ) {
2774					if ( c.rtl && d.delta > 0 || !c.rtl && d.delta <= 0 ) {
2775						/* TODO REMOVE */ //console.log( '>>>>>>>>> next >>>>>>>> ');
2776						if ( c.loop || c.active != c.maxActive ) _this.next( 1 );
2777					} else {
2778						/* TODO REMOVE */ //console.log( '<<<<<<<<< prev <<<<<<<< ');
2779						if ( c.loop || c.active != 1 ) _this.prev( 1 );
2780					}
2781				} else {
2782					_this.change( c.activePosition );
2783				}
2784			}
2785			// если карусель не зацикленная и нет состояния прокрутка проверяем максимальный сдвиг
2786			if ( !c.loop && !_this.isState('scrolling')  ) _this.checkMaxShift();
2787			// запускаем на фрэйм cобытие scroll на случай очень плавного сдвига пользователя
2788			if ( c.motionType == 'scroll' ) _this.$frame.scroll();
2789			// проверка что актичнвый елемент не клон иначе сдвиг на реальный
2790			// if ( c.loop ) _this.toRealActive();
2791			_this.leaveState( 'drag' );
2792			_this.setTrigger( 'dragEnd' );
2793		} else if ( !c.loop ) {
2794			_this.checkMaxShift();
2795		}
2796		/*TODO remove*/ //console.log(' loop = '+c.loop+' scrolling = '+_this.isState( 'scrolling' ));
2797		// очищаем значения для сдвига
2798		_this.dragInfoClear();
2799	};
2800	/** дествия при event scroll  */
2801	theinCarousel.prototype.dragScrolling = function () {
2802		var _this = this,
2803			c = _this._current;
2804		if ( !_this.isState( 'scrolling' ) ) _this.enterState( 'scrolling' );
2805		// очищаем таймаут по которому сработает отмена события скролл и сменятся флаги
2806		/* TODO REMOVE */ //console.log('=== dragScrolling ===  scrolliing = active='+c.active+' activePosition = '+c.activePosition);
2807		clearTimeout( _this.scrollTimer );
2808		if ( !_this.isState( 'change' ) ) {
2809			_this.motionUpdateActive();
2810			_this.updateAddedElements();
2811			_this.setActive( c.active );
2812		}
2813		if ( !_this.isState( 'change' ) && !_this.isState( 'grab' ) && !_this.isState( 'touch' ) ) {
2814			// сдвиг полосы при loop и инерционной докрутке
2815			var x = _this.getPackShift().x,
2816				_x = _this.dragMoveCalc( x, true );
2817			if ( x != _x ) _this.setPackShift( _x, true );
2818			_this.scrollTimer = setTimeout( function () {
2819				/* TODO REMOVE */ //console.log( _this.scrollTimer );
2820				/* TODO REMOVE */ //console.log( 'check max shift' );
2821				_this.toRealActive();
2822				if ( !c.loop && c.motionType != 'scroll' ) _this.checkMaxShift();
2823				if ( c.sticked ) _this.change( c.active );
2824				_this.leaveState( 'scrolling' );
2825			}, 100 );
2826		}
2827	};
2828	/**
2829	 * очистка информации
2830	 * Cleaning Information
2831	 */
2832	theinCarousel.prototype.dragInfoClear = function () {
2833		var d = this._current._drag;
2834		d.itemStart = null;
2835		d.timeStart = null;
2836		d.shiftStart = null;
2837		d.touchStart = null;
2838		d.delta = null;
2839		d.checkDirection = null;
2840	};
2841	/**
2842	 * @param {Event}
2843	 */
2844	theinCarousel.prototype.dragMove = function ( e ) {
2845		var _this = e.data,
2846			c = _this._current,
2847			d = c._drag,
2848			coord = _this.getEventCoord( e ),
2849			x = d.shiftStart.x + ( c.motionType == 'scroll' ? ( d.touchStart.x - coord.x ) : ( coord.x - d.touchStart.x ) );
2850
2851		/*TODO remove*/ //console.log('c.rtl = '+c.rtl +' motionType = '+c.motionType+' shiftStart = '+d.shiftStart.x+' touchStart = '+d.touchStart.x+' coord.x = '+coord.x+' x = '+x);
2852
2853		x = _this.dragMoveCalc( x );
2854		if ( !_this.isState( 'drag' ) ) {
2855			_this.enterState( 'drag' );
2856			_this.setTrigger( 'dragStart' );
2857		}
2858		// проверяем что дельта движения по горизонтали больше чем по вертикали и отменяем сдвиг слайдера если движение по вертикали сильнее
2859		if ( d.checkDirection === false && Math.abs( d.touchStart.x - coord.x ) < Math.abs( d.touchStart.y - coord.y ) ) {
2860			_this.dragEnd();
2861			return false;
2862		} else {
2863			// флаг что проверку на начало сдвига прошла
2864			d.checkDirection = true;
2865		}
2866
2867		// сдвиг пака если это не тач устройство и не скролл сдвиг
2868		if ( !(_this.isState( 'touch' ) && c.motionType == 'scroll') ) _this.setPackShift( x, true );
2869		d.delta = coord.x - d.touchStart.x;
2870		_this.motionUpdateActive();
2871		_this.updateAddedElements();
2872		/* TODO remove */ // console.log(' active '+ c.active);
2873	};
2874	/**
2875	 * Проверка и перерасчет координаты сдвига если вышло за границы активной облоасти
2876	 * @param {Number} coordinate.
2877	 * @param {Boolean} flag.
2878	 * @return {Number} new coordinate.
2879	 * */
2880	theinCarousel.prototype.dragMoveCalc = function ( x, scroll ) {
2881		var _this = this,
2882			c = _this._current,
2883			rtlScroll = ( c.rtl && c.motionType == 'scroll' ) ? true : false,
2884			min = rtlScroll ? -c.limitMax : c.limitMin,
2885			max = rtlScroll ? -c.limitMin : c.limitMax,
2886			added = c.between + ( c.center ? ( ( c.itemsSettings[ 1 ].width + c.itemsSettings[ c.originLength ].width ) / 2 ) : c.itemsSettings[ c.originLength ].width ),
2887			over;
2888		/* TODO REMOVE */ //console.log( '=== dragMoveCalc ===   min( '+min+' ) < x( '+x+' ) < max( '+max+' )    added ='+added );
2889		if ( x < ( ( c.loop && scroll ) ? ( min - added ) : min ) ) {
2890			over = min - x;
2891			/* TODO REMOVE */ //console.log( '=== 1 dragMoveCalc ===  X < MIN ===  over('+over+')   min( '+min+' ) < x( '+x+' ) < max( '+max+' ) ' );
2892			if ( c.loop ) {
2893				over = over - c.itemsOriginWidth.fullWidth * Math.floor( over / c.itemsOriginWidth.fullWidth );
2894				x = min + c.itemsOriginWidth.fullWidth - over;
2895			} else {
2896				x = min - _this.dragMoveReduse( over )
2897			}
2898		} else if ( x > ( ( c.loop && scroll ) ? ( max + added ) : max ) ) {
2899			over = x - max;
2900			/* TODO REMOVE */ //console.log( '=== 2 dragMoveCalc === X > MAX ===  over('+over+')   min( '+min+' ) < x( '+x+' ) < max( '+max+' ) ');
2901			if ( c.loop ) {
2902				over = over - c.itemsOriginWidth.fullWidth * Math.floor( over / c.itemsOriginWidth.fullWidth );
2903				x = max - c.itemsOriginWidth.fullWidth + over;
2904			} else {
2905				x = max + _this.dragMoveReduse( over );
2906			}
2907		}
2908		return x;
2909	};
2910	/**
2911	 * Подсчет уменьшения сдвига на концах
2912	 * @param {Number} coordinate.
2913	 * @return {Number} new coordinate.
2914	 * */
2915	theinCarousel.prototype.dragMoveReduse = function ( x ) {
2916		var c = this._current;
2917		if ( c.motionType != 'scroll' || ( c.motionType == 'scroll' && this.isState( 'grab' ) ) ) {
2918			x = ( c.elasticEnds && ( c.center || c.packWidth > c.frameWidth)) ? ( x / 5 ) : 0;
2919		}
2920		return x;
2921	};
2922	/**
2923	 * получение и обновление номера активного элемента на который сейчас сдвинут пак
2924	 * @param {Number} shift position
2925	 * */
2926	theinCarousel.prototype.motionUpdateActive = function () {
2927		var _this = this,
2928			c = _this._current,
2929			shift = _this.getPackShift().x,
2930			activePosition = c.activePosition;
2931		// пересчет позиции к положительным значениям в зависимости от типа сдвига и направленности
2932		if ( c.motionType == 'scroll' ) {
2933			shift = shift * ( c.rtl ? -1 : 1 );
2934		} else {
2935			shift = shift * ( c.rtl ? 1 : -1 );
2936		}
2937		/* TODO REMOVE */ //console.log('+++ motionUpdateActive === active '+c.active+' activePosition = '+c.activePosition+' ( ' + c.itemsSettings[ c.active ].shift + ' - ' + shift + ' - ' + c.itemsSettings[ ( c.active + 1 )  ].shift +')');
2938		// пересчет активной позиции при сменен итема
2939		activePosition = _this.motionUpdateActiveCalc( shift, activePosition );
2940		// приведение к значимой позиции для не зацикленных
2941		if ( !c.loop ) {
2942			if ( activePosition <= 0 ) {
2943				activePosition = 1;
2944			} else if ( activePosition > c.maxActive || shift > ( c.packFullWidth - c.frameFullWidth - c.elasticShift ) ) {
2945				activePosition = c.maxActive;
2946			}
2947		}
2948		c.activePosition = activePosition;
2949		_this.getRealActive();
2950		return c.activePosition;
2951	};
2952	theinCarousel.prototype.motionUpdateActiveCalc = function ( shift, active ){
2953		if ( !shift ) return false;
2954		var _this = this,
2955			c = _this._current;
2956		if ( !active && active != 0 ) return false;
2957		if ( c.itemsSettings[ active ] && shift < c.itemsSettings[ active ].shift ) {
2958			/* TODO REMOVE */ //console.log( 'active-- = '+active+' maxActivte = '+c.maxActive );
2959			active = _this.motionUpdateActiveCalc( shift, ( active - 1 ) );
2960		} else if ( c.itemsSettings[ ( active + 1 ) ] && shift >= c.itemsSettings[ ( active + 1 ) ].shift ) {
2961			/* TODO REMOVE */ //console.log( 'active++ = '+active+' maxActivte = '+c.maxActive );
2962			active = _this.motionUpdateActiveCalc( shift, ( active + 1 ) );
2963		}
2964		/* TODO REMOVE */ //console.log( 'active++ = '+active+' maxActivte = '+c.maxActive );
2965		return active;
2966	};
2967	theinCarousel.prototype.toRealActive = function(){
2968		var _this = this,
2969			c = _this._current;
2970		/* TODO REMOVE */ //console.log(' === toRealActive === c.active = '+c.active+' activePosition = '+c.activePosition );
2971		if ( c.activePosition < 1 || c.activePosition > c.maxActive ){
2972			_this.setPackShift( _this.dragMoveCalc( _this.getPackShift().x, true ) );
2973			c.activePosition = c.active;
2974		}
2975	};
2976	/* получение реального активного элемента  */
2977	theinCarousel.prototype.getRealActive = function(){
2978		var c = this._current;
2979		if ( c.itemsSettings && c.itemsSettings[ c.activePosition ] ){
2980			c.active = c.itemsSettings[ c.activePosition ].item
2981		}
2982	};
2983	/**
2984	 * проверка максимальной или минимальной позиции пака и сдвиг если вышли за границы
2985	 * calculating the maximum or minimum position of the pack
2986	 * @param {Object} obj
2987	 * @param {String | Object} property | states
2988	 * @param {String/Number | Object} value | states
2989	 */
2990	theinCarousel.prototype.checkMaxShift = function ( fast ) {
2991		var _this = this,
2992			c = _this._current,
2993			shift = _this.getPackShift().x,
2994			rtlScroll = ( c.rtl && c.motionType == 'scroll' ) ? true : false,
2995			min = rtlScroll ? -c.limitMax : c.limitMin,
2996			max = rtlScroll ? -c.limitMin : c.limitMax;
2997		/* TOFO REMOVE */ //console.log('=== Check Max Shift === shift = '+shift+ ' max = '+ max+ ' min = '+min);
2998		var	x = shift > max ? max : shift < min ? min : false;
2999		/* TOFO REMOVE */ //console.log('=== Check Max Shift === x = '+x);
3000		if ( x !== false ) {
3001			_this.setPackShift( x, fast );
3002		}
3003
3004	};
3005
3006	/** ----- Общие методы ----- */
3007
3008	theinCarousel.prototype.getEventCoord = function ( event ) {
3009		var result = {
3010			x: null,
3011			y: null
3012		};
3013		event = event.originalEvent || event || window.event;
3014		event = event.touches && event.touches.length ?
3015			event.touches[ 0 ] : event.changedTouches && event.changedTouches.length ?
3016				event.changedTouches[ 0 ] : event;
3017		if ( event.pageX ) {
3018			result.x = event.pageX;
3019			result.y = event.pageY;
3020		} else {
3021			result.x = event.clientX;
3022			result.y = event.clientY;
3023		}
3024		return result;
3025	};
3026	/**
3027	 * enters a state.
3028	 * @param {String} the state name.
3029	 */
3030	theinCarousel.prototype.enterState = function ( name ) {
3031		$.each( [ name ].concat( this._state.tags[ name ] || [] ), $.proxy( function ( i, name ) {
3032			if ( this._state.current[ name ] === undefined ) {
3033				this._state.current[ name ] = 0;
3034			}
3035			this._state.current[ name ]++;
3036			/* TODO REMOVE */ //console.log(this._state.current);
3037			/* TODO REMOVE */ //console.log(' ► ► ► ► ► '+name+' ► ► ► ► ►' );
3038			this.defShowStates( this._state.current );
3039		}, this ));
3040	};
3041	/**
3042	 * leaves a state.
3043	 * @param {String} the state name.
3044	 */
3045	theinCarousel.prototype.leaveState = function ( name ) {
3046		$.each([ name ].concat( this._state.tags[ name ] || []), $.proxy(function ( i, name ) {
3047			if ( this._state.current[ name ] && this._state.current[ name ] > 0) {
3048				this._state.current[ name ]--;
3049			}
3050			/* TODO REMOVE */ //console.log(this._state.current);
3051			/* TODO REMOVE */ //console.log(' ◄ ◄ ◄ ◄ ◄ '+name+' ◄ ◄ ◄ ◄ ◄' );
3052			this.defShowStates( this._state.current );
3053		}, this ));
3054	};
3055	/**
3056	 * is state
3057	 * @param {String} The state to check.
3058	 * @returns {Boolean}  The flag which indicates if the carousel is busy.
3059	 */
3060	theinCarousel.prototype.isState = function ( name ) {
3061		return this._state.current[ name ] && this._state.current[ name ] > 0;
3062	};
3063	/**
3064	 * проверка мобильный браузер или нет
3065	 * check mobile browser
3066	 * @returns {true | false}
3067	 */
3068	theinCarousel.prototype.mobileBrowser = function () {
3069		var check = false;
3070		( function ( a ) {
3071			if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|
3071sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true;
3072		})( navigator.userAgent || navigator.vendor || window.opera );
3073		return check;
3074	};
3075	/**
3076	 * установка стиля(ей) на объект
3077	 * set style to object
3078	 * @param {Object} obj
3079	 * @param {String | Object} property | states
3080	 * @param {String/Number | Object} value | states
3081	 */
3082	theinCarousel.prototype.setStyle = function ( obj, prop, val ) {
3083		var _this = this;
3084		if ( typeof prop === 'object' ) {
3085			$.each( prop, function ( key, value ) {
3086				_this.setStyle( obj, key, value );
3087			});
3088		} else if ( prop === 'transition' && typeof val === 'object' ) {
3089			_this.setStyleTransition( obj, val );
3090		} else {
3091			obj.css( _this.getPrefixedStyle( obj[ 0 ].style, prop ), val )
3092		}
3093	};
3094	/**
3095	 * установка стиля transition на объект
3096	 * set transition style to object
3097	 * @param {Object} obj
3098	 * @param {Object} states { <prop>, <duration>, <type>, <delay> }
3099	 */
3100	theinCarousel.prototype.setStyleTransition = function ( obj, states ) {
3101		var _this = this;
3102		if ( states.prop === 'none' ) {
3103			obj.css(_this.getPrefixedStyle( obj[ 0 ].style, 'transition' ), 'none' );
3104		} else {
3105			var trProp = ( !states.prop || states.prop == false ) ? '' : _this.getPrefixedStyle( obj[ 0 ].style, states.prop ),
3106				trDuration = ( ( !states.duration && states.duration != 0 ) || states.duration === false ) ? '' : parseInt( states.duration >= 0 ? states.duration : _this.transitionDuration || 100 ) + 'ms',
3107				trType = ( !states.type || states.type === false ) ? '' : states.type || _this.transitionType || 'ease-out',
3108				trDelay = ( states.delay && typeof states.delay == 'number' && states.delay > 0 ) && states.delay ? parseInt( states.delay ) + 'ms' : '';
3109			obj.css( _this.getPrefixedStyle( obj[ 0 ].style, 'transition' ), trProp + ' ' + trDuration + ' ' + trType + ' ' + trDelay );
3110		}
3111	};
3112	/**
3113	 * получение префикса для значения свойства
3114	 * get the prefixed property
3115	 * @param {Object} obj
3116	 * @param {String} property
3117	 * @returns {String | Undefined} prefixed
3118	 */
3119	theinCarousel.prototype.getPrefixedStyle = function ( obj, property ) {
3120		var _this = this,
3121			prefix,
3122			prop,
3123			camelProp = property[ 0 ].toUpperCase() + property.slice( 1 ),
3124			i = 0,
3125			vendor_prefixes = [ '', 'webkit', 'Moz', 'MS', 'ms', 'o' ];
3126		if ( _this.options.vendor_prefixes ) vendor_prefixes = _this.options.vendor_prefixes;
3127		while ( i < vendor_prefixes.length ) {
3128			prefix = vendor_prefixes[ i ];
3129			prop = ( prefix ) ? prefix + camelProp : property;
3130			if ( prop in obj ) {
3131				return prop;
3132			}
3133			i++;
3134		}
3135		return property;
3136	};
3137	/**
3138	 * проверка поддержки css свойства
3139	 * check support for css properties
3140	 * @param {String} property
3141	 * @param {String} value
3142	 * @returns {true | false} Is supported
3143	 */
3144	theinCarousel.prototype.supportsCSS = function ( property, value ) {
3145		var element = document.createElement( 'span' );
3146		property = this.getPrefixedStyle( element, property );
3147		if ( element.style[ property ] !== undefined ) {
3148			element.style.cssText = property + ':' + value;
3149		} else {
3150			return false;
3151		}
3152		return element.style[ property ] === value;
3153	};
3154	/**
3155	 * тригер
3156	 * triggers a public event.
3157	 * @param {String} event name
3158	 * @param {Object} data array or object
3159	 * @param {Object} event object
3160	 */
3161	theinCarousel.prototype.setTrigger = function ( name, data, $obj ) {
3162		if ( typeof name != 'string' ) return false;
3163		var _this = this,
3164			extObj = {
3165				"eventType": name,
3166				"plugin": _this
3167			},
3168			data = ( $.isPlainObject( data ) ) ? $.extend( data, extObj ) : extObj,
3169			$obj = ( typeof $obj == 'object' && $obj.length > 0 ) ? $obj : _this.$element;
3170		$obj.trigger( name + '.' + _this.cl.main, data );
3171	};
3172	/**
3173	 * получение ширины окна клиента
3174	 * @returns {Number} size
3175	 */
3176	theinCarousel.prototype.getClientWidth = function () {
3177		return Math.max( window.innerWidth || 0, (document.getElementsByTagName( 'html' )[ 0 ] || {} ).clientWidth || 0)
3178	};
3179	/**
3180	 * получение высоты окна клиента
3181	 * @returns {Number} size
3182	 */
3183	theinCarousel.prototype.getClientHeigth = function () {
3184		return Math.max( window.innerHeight || 0, (document.getElementsByTagName( 'html' )[ 0 ] || {}
3184 ).clientHeight || 0)
3185	};
3186	/**
3187	 * Translation number or percent number to positive number
3188	 * @param {Number | String} number for translation
3189	 * @return {Number} positive number
3190	 * */
3191	theinCarousel.prototype.toPositiveNumber = function ( number, $el ) {
3192		if ( !number ) {
3193			return 0;
3194		} else if ( typeof number == 'number' ) {
3195			return number >= 0 ? number : 0;
3196		} else if ( typeof number == 'string' ) {
3197			if ( number.indexOf( '%' ) >= 0 ){
3198				var percent = parseInt( number.slice( 0, number.indexOf( '%' ) ) ),
3199					size = ( $el && $el.length > 0 ) ? $el.width() : 0;
3200				if ( percent > 0 && percent <= 100 && size > 0 ) {
3201					return ( size / 100 * percent );
3202				}
3203			} else {
3204				number = parseInt( number );
3205				return ( number >= 0 ? number : 0 );
3206			}
3207		}
3208		return 0;
3209	};
3210	/**
3211	 * Gets viewport width.
3212	 * @return {Number} - The width in pixel.
3213	 */
3214	theinCarousel.prototype.viewportWidth = function() {
3215		var width;
3216		if ( typeof this.options.responsiveBaseElement == 'string' && this.options.responsiveBaseElement.length > 0 ) {
3217			width = $( this.options.responsiveBaseElement ).width();
3218		} else if ( this.options.responsiveBaseElement === true && this.$sizeFrame && this.$sizeFrame.length > 0) {
3219			width = this.$sizeFrame.width()
3220		} else {
3221			width = this.getClientWidth()
3222		}
3223		/*TODO remove */ //console.log(' viewportWidth = '+ width);
3224		return width;
3225	};
3226
3227	/* TODO ВНЕДРИТЬ ПРЕЛОАД КАРТИНОК !!! ПОЗЖЕ !!! */
3228
3229	/**
3230	 * Preloads images with auto width.
3231	 * @todo Replace by a more generic approach
3232	 * @protected
3233	 */
3234	theinCarousel.prototype.preloadAutoWidthImages = function( images ) {
3235		images.each( $.proxy( function( i, element ) {
3236			this.enter('pre-loading');
3237			element = $(element);
3238			$(new Image()).one('load', $.proxy(function(e) {
3239				element.attr('src', e.target.src);
3240				element.css('opacity', 1);
3241				this.leave('pre-loading');
3242				!this.is('pre-loading') && !this.is('initializing') && this.refresh();
3243			}, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));
3244		}, this));
3245	};
3246
3247	/* function for test */
3248	/* TODO delete */
3249	theinCarousel.prototype.defShowStates = function( obj ){};
3250	theinCarousel.prototype.showStates = function( obj ) {
3251		var _this = this,
3252			st = "";
3253		$.each( obj, function( i, v ) {
3254			st = st + '<span class="' + ( _this.prefix + ( v > 0 ? 'show-states-true' : 'show-states-false' ) ) + '">' + i + ' = ' + v + '</span> ';
3255		});
3256		$( _this.options.showStates ).empty().append( $('<div class="' + _this.prefix + 'show-states">' + st + '</div>') );
3257	};
3258
3259
3260	/**
3261	 * The jQuery Plugin for the The-in Carousel
3262	 * @public
3263	 */
3264	$.fn.theinCarousel = function ( options ) {
3265		return this.each(function () {
3266			var instance = $.data( this, 'theinCarousel' );
3267			if ( instance ) {
3268				if ( $.isPlainObject( options )) {
3269					instance.update( options );
3270				} else {
3271					console.log( 'option object is not a plain object' )
3272				}
3273			} else {
3274				$.data( this, 'theinCarousel', new theinCarousel( this, options ) );
3275			}
3276		});
3277	};
3278
3279	/**
3280	 * The constructor for the jQuery Plugin
3281	 * @public
3282	 */
3283	$.fn.theinCarousel.Constructor = theinCarousel;
3284
3285})(jQuery, window, document);
3286
3287
3288
3289
3290
3291/* TODO доделать*/
3292
3293;( function ( $, window, document, undefined ) {
3294	var Navigation = function( carousel ){
3295		/**
3296		 * Reference to the core.
3297		 * @protected
3298		 * @type {Owl}
3299		 */
3300		this._core = carousel;
3301		/**
3302		 * Indicates whether the plugin is initialized or not.
3303		 * @protected
3304		 * @type {Boolean}
3305		 */
3306		this._initialized = false;
3307		/**
3308		 * The carousel element.
3309		 * @type {jQuery}
3310		 */
3311		this.$element = this._core.$element;
3312	};
3313	/**
3314	 * Default options.
3315	 * @public
3316	 */
3317	Navigation.Defaults = {};
3318	/**
3319	 * Initializes the layout of the plugin and extends the carousel.
3320	 * @protected
3321	 */
3322	Navigation.prototype.initialize = function() {};
3323	//$.fn.theinCarousel.Constructor.Plugins.Navigation = Navigation;
3324})(jQuery, window, document);
3325
3326
3327const SHARE_URL = 'SHARE_URL',
3328	SHARE_TITLE = 'SHARE_TITLE',
3329	SHARE_FB_ID = 'SHARE_FB_ID';
3330
3331var riaShare = {
3332	services_sort: [],
3333	options: {
3334		shareFullEl: '.share-full',
3335		shareEl: '.share',
3336		count: 0
3337	},
3338	shareURL:'SHARE_URL',
3339	shareTitle:'SHARE_TITLE',
3340	services: {
3341		facebook: {
3342			id:'facebook',
3343			name: 'Facebook',
3344			popupUrl: `https://www.facebook.com/sharer/sharer.php?u=${SHARE_URL}`,
3345			popupWidth: 600,
3346			popupHeight: 359
3347		},
3348		twitter: {
3349			id:'twitter',
3350			name: 'Twitter',
3351			popupUrl: `https://twitter.com/intent/tweet?url=${SHARE_URL}&text=${SHARE_TITLE}`,
3352			popupWidth: 600,
3353			popupHeight: 250
3354		},
3355		whatsapp: {
3356			id:'whatsapp',
3357			name: 'WhatsApp',
3358			// popupUrl: `whatsapp://send?text=${SHARE_URL}`,
3359			popupUrl: `https://api.whatsapp.com/send?text=${SHARE_TITLE}&url${SHARE_URL}`,
3360			popupWidth: 820,
3361			popupHeight: 500
3362		},
3363		telegram: {
3364			id: 'telegram',
3365		    name: 'Telegram',
3366		    popupUrl: `https://telegram.me/share/url?url=${SHARE_URL}`,
3367		    popupWidth: 820,
3368		    popupHeight: 500
3369		},
3370		vk: {
3371			id: 'vk',
3372			name: 'ВКонтакте',
3373			popupUrl: `https://vk.ru/share.php?url=${SHARE_URL}&title=${SHARE_TITLE}`,
3374			popupWidth: 655,
3375			popupHeight: 450
3376		},
3377		odnoklassniki: {
3378			id: 'odnoklassniki',
3379			name: 'OK',
3380			popupUrl: `https://connect.ok.ru/dk?st.cmd=WidgetSharePreview&service=odnoklassniki&st.shareUrl=${SHARE_URL}`,
3381			popupWidth: 580,
3382			popupHeight: 336
3383		},
3384		messenger: {
3385			id: 'messenger',
3386			name: 'Messenger',
3387			popupUrl: `fb-messenger://share/?link=${SHARE_URL}&app_id=${SHARE_FB_ID}`,
3388			popupWidth: 820,
3389			popupHeight: 500
3390		},
3391		viber: {
3392			id:'viber',
3393			name: 'Viber',
3394			popupUrl: `viber://forward?text=${SHARE_URL}`,
3395			popupWidth: 820,
3396			popupHeight: 500
3397		},
3398		google: {
3399			id:'google',
3400		    name: 'Google+',
3401		    popupUrl: `https://plus.google.com/share?url=${SHARE_URL}`,
3402		    popupWidth: 500,
3403		    popupHeight: 550
3404		},
3405		mailru: {
3406			id:'mailru',
3407		    name: 'Mail.ru',
3408		    popupUrl: `https://connect.mail.ru/share?share_url=${SHARE_URL}&title=${SHARE_TITLE}`,
3409		    popupWidth: 492,
3410		    popupHeight: 500
3411		},
3412		pinterest: {
3413			id:'pinterest',
3414		    name: 'Pinterest',
3415		    popupUrl: `https://pinterest.com/pin/create/button/?url=${SHARE_URL}&description=${SHARE_TITLE}`,
3416		    popupWidth: 740,
3417		    popupHeight: 550
3418		},
3419		flipboard: {
3420			id:'flipboard',
3421		    name: 'Flipboard',
3422		    popupUrl: `https://share.flipboard.com/bookmarklet/popout?v=2&title=${SHARE_TITLE}&url=${SHARE_URL}`,
3423		    popupWidth: 820,
3424		    popupHeight: 500
3425		},
3426		wykop: {
3427			id:'wykop',
3428			name: 'Wykop',
3429			popupUrl: `http://www.wykop.pl/dodaj/link/?url=${SHARE_URL}&title=${SHARE_TITLE}`,
3430			popupWidth: 820,
3431			popupHeight: 500
3432		},
3433		meneame: {
3434			id:'meneame',
3435			name: 'Menéame',
3436			popupUrl: `https://www.meneame.net/submit.php?url=${SHARE_URL}&title=${SHARE_TITLE}`,
3437			popupWidth: 820,
3438			popupHeight: 500
3439		},
3440		hatena: {
3441			id:'hatena',
3442			name: 'Hatena',
3443			popupUrl: `https://b.hatena.ne.jp/site/jp.sputniknews.com/#bookmark_url=${SHARE_URL}`,
3444			popupWidth: 820,
3445			popupHeight: 500
3446		},
3447		weibo: {
3448			id:'weibo',
3449			name: 'Weibo',
3450			popupUrl: `https://service.weibo.com/share/share.php?url=${SHARE_URL}&title=${SHARE_TITLE}`,
3451			popupWidth: 820,
3452			popupHeight: 500
3453		},
3454		wechat: {
3455			id:'wechat',
3456			name: 'WeChat',
3457			// popupUrl: `https://service.weibo.com/share/share.php?url=${SHARE_URL}&title=${SHARE_TITLE}`,
3458			popupWidth: 820,
3459			popupHeight: 500
3460		},
3461		line: {
3462			id:'line',
3463			name: 'Line',
3464			popupUrl: `https://timeline.line.me/social-plugin/share?url=${SHARE_URL}&title=${SHARE_TITLE}`,
3465			popupWidth: 820,
3466			popupHeight: 500
3467		}
3468	},
3469	init: function() {
3470		this.shareModalTemplate();
3471		this.initFullList();
3472		this.initItems( $('body') );
3473
3474		$(window).on('resize', function() {
3475			if ($(riaShare.options.shareFullEl).hasClass('m-article')) {
3476				riaShare.hideFullList();
3477			}
3478			if ($(riaShare.options.shareFullEl).hasClass('active')) {
3479				riaShare.coordFullList();
3480			}
3481		});
3482	},
3483	initItems: function(el) {
3484		var _this = this;
3485		var j = 0;
3486
3487		// var deskServices = Object.keys(_this.services).filter(e => !_this.services[e].mobile).length
3488		// console.log(el.find(this.options.shareEl))
3489		if(!el.find(this.options.shareEl).hasClass('m-active')) {
3490			el.find(this.options.shareEl).addClass('m-active');
3491			for (var i = 0; i < this.services_sort.length; i++) {
3492				if ((this.services_sort[i][3].mobile && riaShare.mobileAndTabletcheck()) || !this.services_sort[i][3].mobile) {
3493					var data = {
3494						name: this.services_sort[i][0],
3495						title: this.services_sort[i][3].name,
3496						url: el.find(this.options.shareEl).attr('data-url'),
3497					}
3498
3499					if (++j <= this.options.count) {
3500						el.find(this.options.shareEl).append(_this.shareBlockTemplate(data));
3501					}
3502				}
3503			}
3504
3505			el.find(this.options.shareEl).each(function () {
3506				if (_this.services_sort.filter(el => !el[3].mobile).length > _this.options.count || !Boolean($(this).data('hidemore'))) {
3507					$(this).append(_this.shareBlockMoreTemplate());
3508				}
3509			})
3510
3511			el.on('click', '.share__more', function (e) {
3512				e.preventDefault()
3513				var shareurl = $(this).closest('[data-url]').attr('data-url');
3514				var sharetitle = $(this).closest('[data-title]').attr('data-title');
3515				var shareid = $(this).closest('[data-id]').attr('data-id');
3516				var shareservice = $(this).closest('[data-id]').attr('name');
3517				if (typeof navigator.share !== 'undefined' && riaShare.mobileAndTabletcheck()) {
3518					navigator.share({
3519						url: shareurl,
3520						title: sharetitle
3521					});
3522
3523					if(typeof ria === 'object') {
3524						ria.dispatch('share',{id:shareid,service:shareservice,url:shareurl,title:sharetitle});
3525					}
3526					if (shareid != '') {
3527						$.get('/services/counter/set/?obj_id=' + shareid + '&obj_type=article&action_type=share');
3528					}
3529
3530				} else {
3531					if ($(this).hasClass('m-active')) {
3532						riaShare.hideFullList();
3533					} else {
3534						var type = false;
3535						if ($(this).parents('.share:first').hasClass('m-article')) {
3536							type = 'article';
3537						} else if ($(this).parents('.share:first').hasClass('m-header')) {
3538							type = 'header';
3539						}
3540						riaShare.showFullList(e, $(this), shareurl, sharetitle, shareid, type);
3541					}
3542				}
3543
3544				$(window).on('scroll.shareFullEl', function () {
3545					if ($(riaShare.options.shareFullEl).hasClass('m-article') || (document.documentElement.clientWidth > 924 && $(riaShare.options.shareFullEl).hasClass('m-header'))) {
3546						riaShare.hideFullList();
3547					}
3548					$(document).off('scroll.shareFullEl');
3549				});
3550			});
3551
3552			el.on('click', '.share a[data-name]', function (e) {
3553				riaShare.serviceClick(e, $(this));
3554			});
3555		}
3556
3557	},
3558	shareBlockTemplate(data){
3559		return $(`<a href="${data.url}" title="${data.name}" class="share__link" data-name="${data.name}"><svg class="svg-icon"><use xlink:href="${ria.getIcon(data.name)}"/></svg></a>`);
3560	},
3561	shareBlockMoreTemplate(){
3562		return $(`<a href="#" title="more" class="share__more"><span class="share__more-desktop"><svg class="svg-icon"><use xlink:href="${ria.getIcon('share')}"/></svg></span><span class="share__more-mobile"><svg class="svg-icon"><use xlink:href="${ria.getIcon('share')}"/></svg></span></a>`);
3563	},
3564	shareFullTemplate(data){
3565		return $(`<li class="share-full__${data.name}"><a href="#" title="${data.name}" data-name="${data.name}"><span class="share-full__icon"><svg class="svg-icon"><use xlink:href="${ria.getIcon(data.name)}"/></svg></span><span class="share-full__text">${data.title}</span></a></li>`);
3566	},
3567	shareModalTemplate(){
3568		const url = (GLOBAL && GLOBAL.www) || location.origin
3569		const title = (GLOBAL && GLOBAL.seo && GLOBAL.seo.title) || document.title
3570		return $('body').append($(`<div class="modal-share-full"></div><div class="share-full" data-url="${url}" data-title="${title}"><ul></ul></div>`));
3571	},
3572	popupUrl(popupUrl, data){
3573		return popupUrl.replace(SHARE_URL,data.url).replace(SHARE_TITLE,data.title).replace(SHARE_FB_ID, (GLOBAL && GLOBAL.social.fbID) || '')
3574	},
3575	initFullList: function( selector ) {
3576		var _this = this;
3577		if (typeof selector === 'undefined') {
3578			selector = this.options.shareFullEl;
3579		}
3580		var share = ((GLOBAL && GLOBAL.share) || []);
3581		var services = share.map(el => this.services[el.name]).filter(e => e);
3582		this.services_sort = [];
3583
3584		for (var j = 0; j < services.length; j++){
3585			this.services_sort.push([services[j].id, parseInt((typeof ria === 'object' && ria.lsGet('ria.share.' + services[j].name)) || 0 ), (j + 1), Object.assign({}, services[j], {mobile: share.find(e => e.name === services[j].id).mobile})]);
3586		}
3587
3588		this.services_sort.sort(function(a, b) {
3589			if (a[1] < b[1]) return 1;
3590			if (a[1] > b[1]) return -1;
3591			if (a[2] < b[2]) return -1;
3592			return 1;
3593		});
3594
3595		for (var i = 0; i < this.services_sort.length; i++) {
3596			if ( ( this.services_sort[i][3].mobile && riaShare.mobileAndTabletcheck() ) || !this.services_sort[i][3].mobile ) {
3597				var data = {
3598					name: this.services_sort[i][0],
3599					title: this.services_sort[i][3].name
3600				}
3601
3602				$( selector ).find(' > ul').append( _this.shareFullTemplate(data));
3603			}
3604		}
3605
3606		$( selector ).on('click', 'a[data-name]', function(e) {
3607			riaShare.serviceClick( e, $(this) );
3608		});
3609	},
3610	serviceClick: function(e, el) {
3611		e.stopPropagation();
3612
3613		var _this = this,
3614			service = el.data('name'),
3615			url = el.closest('[data-url]').attr('data-url'),
3616			title = el.closest('[data-title]').attr('data-title');
3617		var id = el.closest('[data-id]').attr('data-id');
3618
3619		if ( url.lastIndexOf('http', 0) !== 0 ) {
3620			url = GLOBAL.www + url;
3621		}
3622
3623		var data = {
3624			url: GLOBAL.rtl ? encodeURIComponent(encodeURI(url)) : encodeURIComponent( url ),
3625			title: encodeURIComponent( title )
3626		}
3627
3628		if(service === 'wechat'){
3629			if(typeof qrcodegen === 'object'){
3630				let div = $('<div class="share__qr"></div>'),
3631					QRC = qrcodegen.QrCode,
3632					qr = QRC.encodeText(url, QRC.Ecc.MEDIUM),
3633					svg = qr.toSvgString(4);
3634
3635				el.append(div.append(svg));
3636
3637				$(document).on('click.social-wechat', function(e) {
3638					if($(e.target).closest('.share__qr')){
3639						div.remove();
3640						$(document).off('click.social-wechat');
3641						$(document).off('scroll.social-wechat');
3642					}
3643				});
3644
3645				$(document).on('scroll.social-wechat', function(e) {
3646					div.remove();
3647					$(document).off('click.social-wechat');
3648					$(document).off('scroll.social-wechat');
3649				})
3650			}
3651		} else {
3652			this.openPopup(_this.popupUrl(this.services[service].popupUrl, data), {
3653				width: this.services[service].popupWidth,
3654				height: this.services[service].popupHeight
3655			});
3656
3657			ria.lsSet('ria.share.' + service, ( parseInt( ria.lsGet('ria.share.' + service) || 0 ) + 1 ) );
3658			if(typeof ria === 'object') {
3659				ria.dispatch('share',{id,service,url,title});
3660			}
3661		}
3662
3663		if (id != '') {
3664			$.get('/services/counter/set/?obj_id=' + id + '&obj_type=article&action_type=share');
3665		}
3666	},
3667	showFullList: function(e, el, url, title, id, type) {
3668		e.stopPropagation();
3669
3670		$(document).on('click.hideshare', function() {
3671			riaShare.hideFullList();
3672			$(document).off('click.hideshare');
3673		});
3674
3675		if (typeof this.el !== 'undefined' ) {
3676			this.el.removeClass('m-active');
3677		}
3678		this.el = el;
3679		this.el.addClass('m-active');
3680
3681		$(this.options.shareFullEl).attr({
3682			'data-url': url,
3683			'data-title': title,
3684			'data-id': id
3685		});
3686
3687		if (document.documentElement.clientWidth > 924) {
3688			riaShare.coordFullList( type );
3689			$(this.options.shareFullEl).addClass('active');
3690		} else {
3691			$('html').addClass('modal-share');
3692			ria.disablePageScroll(true);
3693
3694			if (document.documentElement.clientWidth < 400) {
3695				$(this.options.shareFullEl).css({'right': '10px', 'left': '10px', 'bottom': '10px'});
3696			} else {
3697				$(this.options.shareFullEl).css({'right': '10px', 'bottom': '10px'});
3698			}
3699			$(this.options.shareFullEl).addClass('active');
3700		}
3701		if ( type == 'article' ){
3702			$(this.options.shareFullEl).addClass('m-article');
3703		} else {
3704			$(this.options.shareFullEl).removeClass('m-article');
3705		}
3706		if ( type == 'header' ){
3707			$(this.options.shareFullEl).addClass('m-header');
3708		} else {
3709			$(this.options.shareFullEl).removeClass('m-header');
3710		}
3711	},
3712	coordFullList: function( type ) {
3713		var cw = document.documentElement.clientWidth,
3714			el = this.el;
3715		if (cw < 400) {
3716			$(this.options.shareFullEl).css({'right': '10px', 'bottom': '10px', 'left': '10px', 'top': 'auto'});
3717		} else if (cw < 925) {
3718			$(this.options.shareFullEl).css({'right': '10px', 'bottom': '10px', 'left': 'auto', 'top': 'auto'});
3719		} else {
3720			var btn_top = el.offset().top,
3721				btn_left = el.offset().left,
3722				btn_width = el.outerWidth(),
3723				btn_height = el.outerHeight(),
3724				window_h = document.documentElement.clientHeight,
3725				window_scroll = window.pageYOffset || document.documentElement.scrollTop,
3726				distance_top = (btn_top - window_scroll),
3727				distance_bottom = (window_scroll + window_h - btn_top),
3728				popup_w = $(this.options.shareFullEl).width(),
3729				popup_h = $(this.options.shareFullEl).height(),
3730				popup_top = (distance_top > distance_bottom) ? btn_top - popup_h - 3 : btn_top + btn_height + 1,
3731				popup_left = btn_left - popup_w + btn_width/2 + 18,
3732				popup_right = btn_left - popup_w - btn_width/2 + 10;
3733
3734			if ( type == 'article') {
3735				popup_top = btn_top - 10;
3736				popup_left = btn_left + btn_width + 10;
3737			}
3738			if (distance_top > distance_bottom) {
3739				$(this.options.shareFullEl).removeClass('m-bottom');
3740			} else {
3741				$(this.options.shareFullEl).addClass('m-bottom');
3742			}
3743
3744			if(GLOBAL && GLOBAL.rtl) {
3745				if($(el).closest(this.options.shareEl).hasClass('m-article')){
3746					$(this.options.shareFullEl).css({'left': popup_right+'px', 'top': popup_top+'px', 'bottom': 'auto', 'right': 'auto'});
3747				}else{
3748					$(this.options.shareFullEl).css({'left': btn_left - btn_width/2 + 6 + 'px', 'top': popup_top+'px', 'bottom': 'auto', 'right': 'auto'});
3749				}
3750			}else{
3751				$(this.options.shareFullEl).css({'left': popup_left+'px', 'top': popup_top+'px', 'bottom': 'auto', 'right': 'auto'});
3752			}
3753		}
3754	},
3755	openPopup: function(url, params) {
3756		var left = Math.round(screen.width/2 - params.width/2);
3757		var top = 0;
3758		if (screen.height > params.height) {
3759			top = Math.round(screen.height/3 - params.height/2);
3760		}
3761
3762		var win = window.open(url, 'sl_' + this.service, 'left=' + left + ',top=' + top + ',' +
3763			'width=' + params.width + ',height=' + params.height + ',personalbar=0,toolbar=0,scrollbars=1,resizable=1');
3764		if (win) {
3765			win.focus();
3766		}
3767		else {
3768			location.href = url;
3769		}
3770		if (typeof this.el != 'undefined') {
3771			riaShare.hideFullList();
3772		}
3773	},
3774	hideFullList: function() {
3775		$('html').removeClass('modal-share');
3776		this.el.removeClass('m-active');
3777		this.el.removeClass('m-article');
3778		ria.disablePageScroll( false );
3779		$(this.options.shareFullEl).css({'left': 'auto', 'top': 'auto', 'bottom': 'auto', 'right': 'auto'}).removeClass('active');
3780	},
3781	mobileAndTabletcheck: function() {
3782		var check = false;
3783		(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
3784		return check;
3785	}
3786}
3787
3788/**
3789 * <a class="l-photoview__open"
3790 *   data-photoview_group="{{ String }}"
3791 *   data-photoview_src="{{ Url }}"
3792 *   data-photoview_sharelink="{ link for share }"
3793 *   data-photoview_sharetitle="{ title for share }"
3794 *   data-photoview_shareid="{ article id for share }"
3795 *   data-photoview_desc="{ description text }"
3796 *   data-photoview_copy="{ copyright text }"
3797 *   data-photoview_copylink="{ copyright link}"
3798 *   data-photoview_extlink="{ photobank link }">
3799 * </a>
3800 *
3801 *
3802 *
3803 *  ОТКРЫТЬ
3804 *
3805 *
3806 *
3807 *
3808 * */
3809
3810
3811;"use strict";
3812
3813var photoViewWidget = {
3814	init: function( options ){
3815		var _this = this;
3816		/** основные слои: контентный и фотослой */
3817		_this.$page = ( options && options.page ) ? options.page : $( "#page" );                // выборка слоя данных
3818		_this.$el = ( options && options.photoview ) ? options.photoview : $( "#photoView" );   // выборка слоя просмотра фото
3819		/** проверка наличия слоев для виджета  */
3820		if ( !_this.$page.length || !_this.$el.length ) {
3821			console.log('It is not possible to initialize photoViewWidget');
3822			return;
3823		}
3824		/** переменные префиксов */
3825		_this.prefix = ( options && options.prefix ) ? options.prefix : 'photoview';
3826		_this.classPrefix = '.' + _this.prefix + '__';
3827		/** НАСТРОЙКИ */
3828		_this.settings = {
3829			updateGroupOpen     : false,                    // обновлять набор элементов каждый раз при открытии галереи (для динамически подгружаемого контента)
3830			loopItems           : true,                     // зацикливать слайды по кругу
3831			durationTransition  : 300,                      // длительность transition в ms
3832			typeTransition      : 'ease-out',               // тип смены слайда
3833			desktopWidth        : 925                       // ширина экрана при которой считается desktop версией
3834		};
3835		/** СОСТОЯНИЯ */
3836		_this.states = {
3837			widgetOpen          : false,                    // флаг photoview открыт
3838			hammerFunc          : true,                     // наличие hammerJS
3839			storeEnabled        : true,                     // поддержка history, флаг надо использовать
3840			storeFromHistory    : false,                    // флаг что пришли из history
3841			itemChanges         : false,                    // флаг "смена слайда"
3842			visibleControls     : true,                     // видимость навигации
3843			ticking             : false                     // флаг "трансформация картинки"
3844		};
3845		/** модификаторы */
3846		_this.modPhotoviewOpen = 'm-photoview-open';                        //
3847		_this.modeBlur = 'm-blur';                                          // класс блюра на слой данных
3848		_this.modeDisabled = 'm-disabled';                                  //
3849		_this.modeOpen = 'm-open';                                          //
3850		_this.modeHidden = 'm-hidden';                                      //
3851		/** view height */
3852		_this.clientHeight = _this.getCh();
3853		/** DATA - атрибуты элемента */
3854		_this.dataGroup =       _this.prefix + '-group';                    // [photoview]-group       атрибут группы
3855		_this.dataSrc =         _this.prefix + '-src';                      // [photoview]-src         атрибут урла картинки
3856		_this.dataImageId =     _this.prefix + '-image-id';                 // [photoview]-image-id    атрибут id картинки
3857		_this.dataShareLink =   _this.prefix + '-sharelink';                // [photoview]-sharelink   атрибут линк для шары
3858		_this.dataShareTitle =  _this.prefix + '-sharetitle';               // [photoview]-sharetitle  атрибут заголовок для шары
3859		_this.dataShareId =     _this.prefix + '-shareid';                  // [photoview]-shareid     атрибут id статьи для шары
3860		/** STORE */
3861		_this.store = {
3862			name : 'pv',    // параметр в урле для хранения состояния
3863			group : 'g',    // параметр в атрибуте идентификатор группы
3864			photo : 'p'     // параметр в атрибуте идентификатор фото
3865		};
3866		/** items info */
3867		_this.group = {
3868			id : false,     // номер набора элементов
3869			$items: false,  // выборка слайдов
3870			length : false  // кол-во слайдов
3871		};
3872		/*_this.sub = {
3873			$obj: false
3874		};*/
3875		/** картинка и параметры трансформации */
3876		_this.image = {
3877			$obj : false,       // объект картинки
3878			size : {
3879				w: false,       // ширина картинки
3880				h: false        // высота картинки
3881			},
3882			translate : {
3883				start_x : false,    // начало отсчета по x для сдвига картинки
3884				start_y : false,    // начало отсчета по y для сдвига картинки
3885				x : false,          // значение x для трансформации
3886				y : false           // значение y для трансформации
3887			},
3888			scale : {
3889				actual : false,     // значение scale
3890				min : 1,            // минимальное значение scale
3891				max : 3,            // максимальное значнеие scale
3892				step : 5            // шаг в процентах при зумировании колесиком
3893			},
3894			origin : {
3895				x: false,           // значение origin x для трансформации
3896				y: false            // значение origin y для трансформации
3897			}
3898		};
3899		/** инфа по Активному слайду */
3900		_this.itemActive = {
3901			$obj : false,
3902			index : false,
3903			src : false
3904		};
3905		/** инфа по следующему слайду */
3906		_this.itemPrev = {
3907			$obj : false,
3908			index : false,
3909			src: false
3910		};
3911		/** инфа по предыдущему слайду */
3912		_this.itemNext = {
3913			$obj : false,
3914			index : false,
3915			src: false
3916		};
3917		/** сохраненние состояний страницы */
3918		_this.saveElStates = {
3919			bodyTop : 0,         // позиция контента по вертикали
3920			bodyLeft : 0,        // позиция контента по горизонтали
3921			htmlTop : 0,
3922			htmlLeft : 0,
3923			bodyOverflow : false
3924		};
3925		/** массив селекторов / объектов с динамической позицией исключений из области клика */
3926		_this.exceptionDуnamicTap = [
3927			_this.getBy( _this.classPrefix + 'desc' )
3928		];
3929		_this.disabledHideControls = false;                 // флаг что был тап по элементу исключения
3930		/** массив селекторов / объектов исключений из области клика */
3931		_this.exceptionTap = [
3932			_this.getBy( _this.classPrefix + 'social' ),    // для статичных объктов
3933			_this.classPrefix + 'desc a',                   // для объектов создаваемых динамически
3934			_this.getBy( _this.classPrefix + 'btn-prev' ),
3935			_this.getBy( _this.classPrefix + 'btn-next' )
3936		];
3937		/** массив селекторов / объектов с переключением видимосии в зависимости от рамеров экрана */
3938		_this.variableVisibility = [
3939			_this.getBy( _this.classPrefix + 'btn-prev i' ),    // иконка кнопка Prev
3940			_this.getBy( _this.classPrefix + 'btn-next i' )     // иконка кнопка Next
3941		];
3942		/** префиксы браузеров для подстановки стилей с префиксами */
3943		_this.vendor_prefixes = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
3944		/** Hammer */
3945		_this.hammerManager = false;
3946		/** Навешиваем стили на слои */
3947		_this.setStyle( _this.$page,{
3948			'position':'relative',
3949			'width':'100%'
3950		});
3951		_this.setStyle( _this.$el,{
3952			'position':'absolute',
3953			'top': 0,
3954			'right': 0,
3955			'left': 0,
3956			'z-index': 1015,
3957			'display':'none',
3958		});
3959		/* Запуск кастомного скролла */
3960		/* !!! обязательно до  update$Obj иначе осхранятся не корректные указатели !!! */
3961		if( typeof photoViewWidget !==  'undefined' ) {
3962			_this.getBy( this.classPrefix + 'desc-over' ).theinScroll({
3963				theme : 'default-light',
3964				autoHide : false
3965			});
3966		}
3967		/** Создаем объекты для работы */
3968		_this.update$Obj();
3969		/** Вызов обработчиков */
3970		_this.addHandlers();
3971	},
3972	update$Obj : function(){
3973
3974		this.$buttonPrev = this.getBy( this.classPrefix + 'btn-prev' );
3975		this.$buttonNext = this.getBy( this.classPrefix + 'btn-next' );
3976		this.$buttonClose = this.getBy( this.classPrefix + 'btn-close' );
3977		this.$canHide = this.getBy( this.classPrefix + 'can-hide' );
3978
3979		this.$sub = this.getBy( this.classPrefix + 'sub' );
3980
3981		this.$itemPrev = this.getBy( this.classPrefix + 'prev' );
3982		this.$itemActive = this.getBy( this.classPrefix + 'active' );
3983		this.$itemNext = this.getBy( this.classPrefix + 'next' );
3984
3985		this.$placeIndexView = this.getBy( this.classPrefix + 'index-view' );
3986		this.$placeSocial = this.getBy( this.classPrefix  + 'social' );
3987
3988		this.$desc = this.getBy( this.classPrefix + 'desc' );
3989		this.$descMore = this.getBy( this.classPrefix + 'desc-more' );
3990		this.$descOver = this.getBy( this.classPrefix + 'desc-over' );
3991		this.$descSize = this.getBy( this.classPrefix + 'desc-size' );
3992		this.$descText = this.getBy( this.classPrefix + 'desc-text' );
3993
3994	},
3995	/**
3996	 * Обработчики
3997	 */
3998	addHandlers: function(){
3999		var _this = this;
4000		/* Если нет Hammerjs выставляем флаг false */
4001		if ( typeof Hammer === 'function' ){
4002			_this.touchInitHammer();
4003		} else {
4004			_this.states.hammerFunc = false;
4005		}
4006		/* Предыдущий слайд */
4007		_this.$buttonPrev.on( 'click', function( e ){
4008			e.preventDefault();
4009			_this.changePrev();
4010		});
4011		/* Следующий слайд */
4012		_this.$buttonNext.on( 'click', function( e ){
4013			e.preventDefault();
4014			_this.changeNext();
4015		});
4016		/* Запрет сдвига картинок и описания */
4017		$( _this.classPrefix + 'img, ' + _this.classPrefix + 'controls a').on( 'dragstart drag dragstop', function(){
4018			return false;
4019		});
4020		/* Открытие галереи по клику на элемент с data src */
4021		$('body').on( 'click', _this.classPrefix + 'open[data-' + _this.dataSrc + ']', function( e ){
4022			e.preventDefault();
4023			_this.open({
4024				clickObj: $( this )
4025			});
4026		});
4027		/* Закрытие photoview по клику на крестик */
4028		_this.$buttonClose.on( 'click', function( e ){
4029			e.preventDefault();
4030			_this.close();
4031		});
4032		/** ИЗМЕНЕНИЯ РАЗМЕРОВ ОКНА БРАУЗЕРА */
4033		$(window).resize( function(){
4034			/** видимость, позиция и размеры элементов фотовью */
4035			_this.clientHeight = _this.getCh();
4036			_this.setPhotoviewHeight();
4037			_this.posLayerTop();
4038			_this.visibilityEl();
4039			_this.updateDataSize();
4040			/** данные о трансформации картинки */
4041			//_this.imageDataSizeUpdate();
4042		});
4043		/** WINDOW SCROLL */
4044		$( window ).scroll( function(){
4045			_this.posLayerLeft();
4046		});
4047		/** MOUSE SCROLL Y */
4048		//_this.addOnWheelY();
4049		_this.$descMore.on( 'click', function(){
4050			_this.showDescMore();
4051		});
4052		/* Выставлям клик на объекты с динамичским позиционированием чтобы отменять тап */
4053		$.each( _this.objArrCreate( _this.exceptionDуnamicTap ), function( i, v ){
4054			$( v ).on( 'click', function(){
4055				_this.disabledHideControls = true;
4056			});
4057		});
4058
4059		/* Запускаем ресайз для образмеривания элементов */
4060		$( window ).resize();
4061		/* Проверяем поддержку history подписываемся на события history урл на наличие параметра галереи */
4062		_this.storeHistory();
4063	},
4064	/**
4065	 * Прокрутка колесика над слоем фотовью для увеличения / усменьшения изображения
4066	 */
4067	addOnWheelY: function() {
4068		if ( this.$el[ 0 ].addEventListener ) {
4069			if ( 'onwheel' in document ) {
4070				this.$el[ 0 ].addEventListener( "wheel", $.proxy( this.addOnWheelYHandler, this ) );
4071			} else if ( 'onmousewheel' in document ) {
4072				this.$el[ 0 ].addEventListener( "mousewheel", $.proxy( this.addOnWheelYHandler, this ) );
4073			} else {
4074				this.$el[ 0 ].addEventListener( "MozMousePixelScroll", $.proxy( this.addOnWheelYHandler, this ) );
4075			}
4076		} else {
4077			this.$el[ 0 ].attachEvent( "onmousewheel", this.addOnWheelYHandler );
4078		}
4079	},
4080	/**
4081	 * Обработка прокрутки и вызов функции зума
4082	 */
4083	addOnWheelYHandler : function( e ){
4084		e.preventDefault();
4085		var _this = this,
4086			delta = e.deltaY || e.detail || e.wheelDelta,
4087			clientX = e.clientX || false,
4088			clientY = e.clientY || false,
4089			scale = false,
4090			percentStep = _this.image.scale.actual/100*_this.image.scale.step;
4091
4092		if ( delta > 0 ){
4093			scale = _this.image.scale.actual - percentStep < _this.image.scale.min ? _this.image.scale.min : _this.image.scale.actual - percentStep;
4094		} else if ( delta < 0 ){
4095			scale = _this.image.scale.actual + percentStep > _this.image.scale.max ? _this.image.scale.max : _this.image.scale.actual + percentStep;
4096		}
4097		if ( scale ){
4098			_this.imageScaling({
4099				x : clientX,
4100				y : clientY,
4101				scale : scale,
4102				duration : 0
4103			});
4104		} else {
4105			return false;
4106		}
4107	},
4108	/**
4109	 * Создание массива объектов из массива селекторов
4110	 * Creating an array from an array of selectors
4111	 * @param {Array} selectors or objects array
4112	 * @returns {Array} objects array
4113	 */
4114	objArrCreate: function( selectorsArr ){
4115		var _this = this,
4116			objArr = [];
4117		$.each( selectorsArr, function( i, v ){
4118			var $obj = v;
4119			if ( typeof v === 'string' ){
4120				$obj = _this.getBy( v )
4121			}
4122			if ( typeof $obj === 'object' && $obj.length > 0 ){
4123				$.each ( $obj, function( k, l ){
4124					objArr.push( $( l ) );
4125				})
4126			}
4127		});
4128		return objArr;
4129	},
4130	/**
4131	 * Проверка попадания координат в несколько областей
4132	 * Checking hit coordinates in several areas
4133	 * @param {Number} coordinate X
4134	 * @param {Number} coordinate y
4135	 * @param {Object / Array objects} objects
4136	 * @returns {Boolean} true / false
4137	 */
4138	hitInArr: function( x, y, obj ){
4139		var _this = this;
4140		if ( x && y && typeof obj === 'object' ) {
4141			if ( obj instanceof Array ){
4142				var state = false;
4143				$.each( obj, function( index, value ){
4144					if ( _this.hitIn( x, y, value ) ) {
4145						state = true;
4146						return;
4147					}
4148				});
4149				return state;
4150			} else {
4151				return  _this.hitIn( x, y, obj );
4152			}
4153		} else {
4154			return false;
4155		}
4156	},
4157	/**
4158	 * Проверка попадания координат в одну область
4159	 * Checking hit coordinates in one area
4160	 * @param {Number} coordinate X
4161	 * @param {Number} coordinate y
4162	 * @param {Object} one object
4163	 * @returns {Boolean} true / false
4164	 */
4165	hitIn: function( x, y, obj ){
4166		var l = obj.offset().left,
4167			r = l + obj.outerWidth(),
4168			t = obj.offset().top,
4169			b = t + obj.outerHeight();
4170		//console.log(l+' - '+x+' - '+r+' === '+t+' - '+y+' - '+b);
4171		//console.log(( x >= l && x <= r && y >= t && y <= b ) ? true : false );
4172		return ( x >= l && x <= r && y >= t && y <= b ) ? true : false;
4173	},
4174
4175	/** TOUCH EVENTS */
4176	touchInitHammer: function(){
4177		//console.log(' INIT HAMMER ');
4178		var _this = this;
4179		_this.hammerManager = new Hammer.Manager( _this.$el[ 0 ] );
4180		//  PAN
4181		_this.hammerManager.add(
4182			new Hammer.Pan({
4183				event: 'pan',
4184				threshold: 0,
4185				pointers: 0
4186			})
4187		);
4188		//  SWIPE
4189		_this.hammerManager.add(
4190			new Hammer.Swipe({
4191				event: 'swipe'
4192			})
4193		)
4194		_this.hammerManager
4195			.get( 'swipe' )
4196			.recognizeWith( 'pan' );
4197		//  PINCH
4198		_this.hammerManager.add(
4199			new Hammer.Pinch({
4200				threshold: 0
4201			})
4202		).recognizeWith(_this.hammerManager.get('pan'));
4203		//  TAB and DOUBLETAP
4204		_this.hammerManager.add(
4205			new Hammer.Tap({
4206				event: 'doubletap',
4207				taps: 2
4208			})
4209		);
4210		_this.hammerManager.add(
4211			new Hammer.Tap({
4212				event: 'tap',
4213				taps: 1
4214			})
4215		);
4216		_this.hammerManager
4217			.get( 'doubletap' )
4218			.recognizeWith( 'tap' );
4219		_this.hammerManager
4220			.get( 'tap' )
4221			.requireFailure( 'doubletap' );
4222		// on action
4223		_this.hammerManager.on( "pinchstart pinchmove pinchend", function( ev ) {
4224			_this.touchPinch( ev )
4225		});
4226		_this.hammerManager.on("panstart panmove panend", function( ev ){
4227			_this.touchPan(ev)
4228		});
4229		_this.hammerManager.on("swipeleft swiperight swipeup swipedown", function( ev ){
4230			_this.touchSwipe( ev )
4231		});
4232		_this.hammerManager.on("tap", function( ev ){
4233			_this.touchTap( ev )
4234		});
4235		_this.hammerManager.on("doubletap", function( ev ){
4236			_this.touchDoubleTap( ev )
4237		});
4238	},
4239	touchPinch: function (ev){
4240		//console.log(ev.type);
4241	},
4242	touchPan: function (ev){
4243		var _this = this;
4244		//console.log('toch pan = '+_this.image.scale.actual);
4245		/*if ( _this.image.scale.actual > 1 ){
4246			if  (ev.type == 'panstart') {
4247				_this.image.translate.start_x = _this.image.translate.x;
4248				_this.image.translate.start_y = _this.image.translate.y;
4249			}
4250			if (ev.type == 'panstart' || ev.type == 'panmove'){
4251				_this.image.translate.x = _this.image.translate.start_x + (ev.deltaX / _this.image.scale.actual );
4252				_this.image.translate.y = _this.image.translate.start_y + (ev.deltaY / _this.image.scale.actual );
4253				_this.requestElTransform({
4254					transformStyle: {
4255						'transform': 'scale3d(' + _this.image.scale.actual + ', ' + _this.image.scale.actual + ', 1) ' +
4256						'translate3d(' + _this.image.translate.x + 'px, ' + _this.image.translate.y + 'px, 0)'
4257					}
4258				});
4259			}
4260			//else if (ev.type = 'panend'){
4261			 //_this.image.translate.start_x = _this.image.translate.x;
4262			 //_this.image.translate.start_y = _this.image.translate.y;
4263			 //}
4264		}*/
4265		if ( $(ev.target).closest('.m-open .the-in-scroll__content').length ) {
4266			var scrollBox = _this.$descOver.find('.the-in-scroll__box');
4267			if (ev.type == 'panstart') {
4268				scrollBox.data('scrollTop', scrollBox.scrollTop() );
4269			}
4270			if (ev.type == 'panmove') {
4271				scrollBox.scrollTop( scrollBox.data('scrollTop') - ev.deltaY );
4272			}
4273		}
4274	},
4275	touchSwipe: function (ev){
4276		var _this = this;
4277		if (ev.type == 'swiperight'){
4278			_this.changePrev();
4279		} else if (ev.type == 'swipeleft'){
4280			_this.changeNext();
4281		}/* else if (ev.type == 'swipeup' || ev.type == 'swipedown'){
4282		 _this.close();
4283		 }*/
4284	},
4285	touchTap: function(ev) {
4286		var _this = this;
4287		//console.log( ev.type + ' x = ' + ev.center.x + ', y = ' + ev.center.y );
4288		if ( !this.disabledHideControls && !_this.hitInArr( ev.center.x, ev.center.y, _this.objArrCreate( _this.exceptionTap ) ) ){
4289			this.controlsToggle();
4290		} else if ( this.disabledHideControls ){
4291			this.disabledHideControls = false;
4292		}
4293	},
4294	touchDoubleTap: function (ev) {
4295		var _this = this;
4296		//console.log(ev.type + ' x = ' + ev.center.x + ', y = ' + ev.center.y );
4297		/*if (!_this.hitInArr(ev.center.x, ev.center.y, _this.objArrCreate( _this.exceptionTap ) ) ){
4298		   _this.imageScaling({
4299			   x : ev.center.x,
4300			   y : ev.center.y
4301		   });
4302	   }*/
4303	},
4304	checkElPosition: function(){
4305
4306	},
4307	/**
4308	 * requestAnimationFrame
4309	 */
4310	/*requestElUpdate: function(param){
4311	 var _this = this;
4312	 if (!_this.ticking){
4313	 _this.requestElAnimFrame(function() {
4314	 _this.requestElTransform(param)
4315	 });
4316	 _this.ticking = true;
4317	 }
4318	 },
4319	 requestElAnimFrame: function(func){
4320	 var requestAnimationFrame = window.requestAnimationFrame ||
4321	 window.mozRequestAnimationFrame ||
4322	 window.webkitRequestAnimationFrame ||
4323	 window.msRequestAnimationFrame ||
4324	 function(func){
4325	 window.setTimeout(func, 1000 / 60);
4326	 };
4327	 requestAnimationFrame(func);
4328	 },*/
4329	requestElTransform: function(param) {
4330		var _this = this,
4331			transformDurationBefore = 0,
4332			transformDuration = 0;
4333
4334		// если есть объект стилей навешиваем до трансформации
4335		if ( param && typeof param.transformStyleBefore == 'object' && $(param.transformStyleBefore).length > 0){
4336			transformDurationBefore = param.transformDurationBefore || 10;
4337			console.log(' set transform style before ');
4338			_this.setStyle(_this.image.$obj, param.transformStyleBefore);
4339		}
4340
4341		setTimeout(function(){
4342
4343			if ( param && typeof param.transformStyle == 'object' && $(param.transformStyle).length > 0){
4344				transformDuration = (param.transformStyle.transition && param.transformStyle.transition.duration) ? param.transformStyle.transition.duration : (_this.settings.durationTransition || 100) ;
4345				console.log(' set transform style ');
4346				_this.setStyle(_this.image.$obj, param.transformStyle);
4347			}
4348
4349			setTimeout(function(){
4350				if ( param && typeof param.transformStyleAfter == 'object' && $(param.transformStyleAfter).length > 0){
4351					console.log(' set transform style after ');
4352					_this.setStyle(_this.image.$obj, param.transformStyleAfter);
4353				}
4354				// если передан callback выполняем
4355				if (param && typeof param.callBack === 'function'){
4356					console.log(' set transform callback ');
4357					param.callBack(_this);
4358				}
4359			}, transformDuration );
4360
4361
4362		}, transformDurationBefore );
4363
4364	},
4365
4366	/** ИНФА по активной картинке */
4367	imageDataReset: function(){
4368		var _this = this;
4369		_this.image.$obj = $( _this.classPrefix + 'img', _this.$itemActive );
4370		_this.imageDataSizeUpdate();
4371		_this.image.scale.actual = 1;
4372		_this.image.origin.x = _this.image.size.w / 2;
4373		_this.image.origin.y = _this.image.size.h / 2;
4374		_this.image.translate.x =_this.image.translate.start_x = 0;
4375		_this.image.translate.y =_this.image.translate.start_y = 0;
4376	},
4377	imageDataSizeUpdate: function(){
4378		if ( typeof this.image.$obj == 'object' && this.image.$obj.length == 1) {
4379			this.image.size.w = this.image.$obj.width();
4380			this.image.size.h = this.image.$obj.height();
4381		}
4382	},
4383	imageCentering: function(){
4384
4385	},
4386	imageTranslateOrigin: function( origin, coord, scaleActual ){
4387		return ( ( ( ( origin - this.image.origin[ coord ] ) * ( scaleActual - 1 ) ) / scaleActual ) + this.image.translate[ coord ] );
4388	},
4389	imageTranslateZoom: function( scaleActual, scaleTo, coord ){
4390		return ( this.image.translate[ coord ] * scaleActual / scaleTo );
4391	},
4392	imageScaling: function( param ){
4393		if ( !param ) return false;
4394		console.log( '*** ', param );
4395		var _this = this,
4396			elW = _this.$el.width(),                //TODO width контейнера
4397			elH = _this.$el.height(),               //TODO height контейнера
4398			elL = _this.$el.offset().left,          //TODO offset.left контейнера
4399			elT = _this.$el.offset().top,           //TODO offset.top контейнера
4400			imgW = _this.image.$obj.width(),        //TODO width картинки
4401			imgH = _this.image.$obj.height(),       //TODO height картинки
4402			imgL = _this.image.$obj.offset().left,  //TODO offset.left картинки
4403			imgT = _this.image.$obj.offset().top,   //TODO offset.top картинки
4404			// короткие записи для SCALE
4405			scaleActual = _this.image.scale.actual, //TODO нынешний scale
4406			scaleMin = _this.image.scale.min,       //TODO минимальный размер scale картинки
4407			scaleMax = _this.image.scale.max,       //TODO максимальный размер scale картинки
4408			scaleTo = param.scale || ( scaleActual >
4408 scaleMin ? scaleMin : scaleMax ); //TODO переданный scale или вычисляется если не передан
4409
4410		_this.image.scale.actual = scaleTo;
4411
4412		// координаты клика по экрану
4413		var	x = param.x || ( elW / 2 ) + elL,       //TODO половина ширины контейнер + левый офсет контейнера
4414			y = param.y || ( elH / 2 ) + elT,       //TODO половина высотф контейнер + верхний офсет контейнера
4415			// координаты клика / центра зумирования на картинке
4416			originX = ( x - imgL ) / scaleActual,     //TODO координата X центра зумирования на картинке
4417			originY = ( y - imgT ) / scaleActual;     //TODO координата Y центра зумирования на картинке
4418
4419
4420		/*	console.log(' ');
4421		 console.log(' ');
4422		 console.log(' ');
4423		 console.log('=================================================================');
4424		 console.log('=   ON SCREEN   X = '+x+', Y = '+y+', scale actual = '+_this.image.scale.actual);
4425		 console.log('= ---------------------------------------------------------------');
4426		 console.log('=   ELEMENT     Width = '+elW+', Height = '+elH);
4427		 console.log('=               OffsetLeft = '+elL+', OffsetTop = '+elT);
4428		 console.log('= ---------------------------------------------------------------');
4429		 console.log('=   IMAGE       Width = '+imgW+', Height = '+imgH);
4430		 console.log('=               OffsetLeft = '+imgL+', OffsetTop = '+imgT);
4431		 console.log('= ---------------------------------------------------------------');
4432		 console.log('=   SCALE       actual = '+scaleActual+', new = '+scaleTo);
4433		 console.log('=               min = '+scaleMin+', max = '+scaleMax);
4434		 console.log('= ---------------------------------------------------------------');
4435		 console.log('=   ON IMAGE    X = '+originX+', Y = '+originY);
4436		 console.log('= ---------------------------------------------------------------');*/
4437
4438
4439		/** подсчет translate3d для нового origin без изменения Zoom */
4440		var translateOriginX = ( ( (originX - _this.image.origin.x ) * (scaleActual-1) ) / scaleActual ) + _this.image.translate.x;
4441		var translateOriginY = ( ( (originY - _this.image.origin.y ) * (scaleActual-1) ) / scaleActual ) + _this.image.translate.y;
4442
4443
4444
4445		/**     подсчет translate3d для нового zoom без изменения Origin                */
4446		/**     x * actualScale - узнаем реальный сдвиг картинки                        */
4447		/**     x * actualScale / scaleTo - узнаем оригинальный параметр сдвига         */
4448		var translateZoomX = _this.image.translate.x * scaleActual / scaleTo;
4449		var	translateZoomY = _this.image.translate.y * scaleActual / scaleTo;
4450
4451
4452		var translateZoomOrigin =   _this.image.translate.x;
4453
4454
4455
4456
4457		/** */
4458		var translateOriginXAfter = (((imgW/2 - originX )*(scaleTo-1))/scaleTo) + translateZoomX;
4459		var translateOriginYAfter = (((imgH/2 - originY )*(scaleTo-1))/scaleTo) + translateZoomY;
4460
4461		originX = 600;
4462		originY = 200;
4463
4464		/*var translate_x = ((_this.image.size.w / 2) - originX) / scaleTo * (scaleTo-1),
4465		 translate_y =((_this.image.size.h / 2) - originY) / scaleTo * (scaleTo-1);*/
4466
4467		var testX = _this.image.origin.x - (((originX - _this.image.origin.x)*(scaleTo-1)/scaleTo) - (originX - _this.image.origin.x));
4468		var testY = _this.image.origin.y - (((originY - _this.image.origin.y)*(scaleTo-1)/scaleTo) - (originY - _this.image.origin.y));
4469
4470
4471
4472		_this.setStyle(_this.image.$obj, {
4473			'transform': 'scale3d(' + scaleTo + ', ' + scaleTo + ', 1) ' +
4474			'translate3d('+translateZoomX+'px, '+translateZoomY+'px, 0)'
4475		});
4476
4477
4478		_this.image.translate.x = translateZoomX;
4479		_this.image.translate.y = translateZoomY;
4480		_this.image.scale.actual = scaleTo;
4481
4482
4483		/*_this.requestElTransform({
4484		 transformStyleBefore : {
4485		 'transform-origin': originX + 'px ' + originY + 'px 0px',
4486		 'transform': 'scale3d(' + scaleActual + ', ' + scaleActual + ', 1) ' +
4487		 'translate3d('+translateOriginX+'px, '+translateOriginY+'px, 0)'
4488		 },
4489		 transformStyle : {
4490		 'transform-origin': originX + 'px ' + originY + 'px 0px',
4491		 'transform': 'scale3d(' + scaleTo + ', ' + scaleTo + ', 1) ' +
4492		 'translate3d('+translateZoomX+'px, '+translateZoomY+'px, 0)'
4493		 },
4494		 transformStyleAfter : {
4495		 'transform-origin': imgW/2 + 'px ' + imgH/2 + 'px 0px',
4496		 'transform': 'scale3d(' + scaleTo + ', ' + scaleTo + ', 1) ' +
4497		 'translate3d('+translateOriginXAfter+'px, '+translateOriginYAfter+'px, 0)'
4498		 },
4499		 callBack : function(__this){
4500		 _this = __this || this;
4501		 _this.image.translate.x = translateZoomX;
4502		 _this.image.translate.y = translateZoomY;
4503		 _this.image.scale.actual = scaleTo;
4504		 }
4505		 });*/
4506
4507
4508
4509
4510
4511		console.log('originX = '+_this.image.origin.x+', originY = '+_this.image.origin.y+' translateX = '+_this.image.translate.x+' translateY = '+ _this.image.translate.y+' scale = '+_this.image.scale.actual);
4512
4513
4514		/*_this.requestElTransform({
4515		 transformDurationBefore : 5,
4516		 transformStyleBefore : {
4517		 'transform-origin': originX + 'px ' + originY + 'px 0px',
4518		 'transform': 'scale3d(' + scaleActual + ', ' + scaleActual + ', 1) ' +
4519		 'translate3d('+trXforNewOrigin+'px, '+trYforNewOrigin+'px, 0)'
4520		 },
4521		 transformStyle : {
4522		 transition : {
4523		 prop: 'none'
4524		 },
4525		 transform: 'scale3d(' + scaleTo + ', ' + scaleTo + ', 1) ' +
4526		 'translate3d('+trXforNewOrigin+'px, '+trYforNewOrigin+'px, 0)'
4527		 },
4528
4529		 callBack : function(__this){
4530		 _this = __this || this;
4531
4532		 _this.setStyle(_this.image.$obj, {
4533		 'transform-origin': originX + 'px ' + originY + 'px 0px',
4534		 transform: 'scale3d(' + scaleTo + ', ' + scaleTo + ', 1) ' +
4535		 'translate3d(' + translate_x + 'px, ' + translate_y + 'px, 0)'
4536		 });
4537
4538		 // записываем измененные данные
4539		 *//**//*_this.image.translate.x = translate_x;
4540		 _this.image.translate.y = translate_y;*//**//*
4541		 _this.image.scale.actual = scaleTo;
4542		 }
4543		 });*/
4544
4545
4546
4547
4548
4549	},
4550
4551	/** open photo view */
4552	open: function( params ){
4553		//console.log('OPEN PHOTOVIEW ',params);
4554		var _this = this;
4555		// Если нет номера группы - присваиваем false
4556		if ( !params.group ) params.group = false;
4557		// Обновляем набор эелментов группы если:
4558		// - выствален флаг принудительного обновления каждый раз
4559		// - номер группы false - открыть одну картинку
4560		// - номер группы не совпадает с ранее отрытой
4561		// - нет набора элементов
4562		// - нет кол-ва элементов
4563		if (  _this.settings.updateGroupOpen || params.group === false || _this.group.id != params.group || !_this.group.$items || !_this.group.length ) {
4564			_this.updateItemsGroup( params );
4565		}
4566		// Если в выборке нет элементов выходим
4567		if ( _this.group.length <= 0 ) {
4568			console.log( 'PhotoViewWidget ERROR - no items group length' );
4569			return false;
4570		}
4571		// Записываем номер активного слайда
4572		_this.itemActive.index = 0;           // по умолчанию 0
4573		if ( typeof params.clickObj == 'object' ) {  // если передан объект клика берем индекс из группы
4574			_this.itemActive.index = _this.group.$items.index( params.clickObj );
4575		} else if ( params.photo ){                   // если передан store номер фото берем индекс из группы по совпадению со store
4576			var storeObj = _this.group.$items.filter( function(){
4577				return $( this )[ 0 ].photoViewWidget_photo == params.photo ? $( this ) : false;
4578			});
4579			if ( storeObj.length == 1 ){
4580				_this.itemActive.index = _this.group.$items.index( storeObj );
4581			}
4582		}
4583		/* если была открыта галерея закрываем */
4584		if( _this.visibleView() ) {
4585			_this.close();
4586		}
4587		/* записывыаем данные о активном, предыдущем и последующем слайдах */
4588		_this.getItemsData();
4589		/* показываем слой с кнопками */
4590		_this.controlsShow();
4591		/* Скрываем слой описания */
4592		_this.activeDataVisible( false );
4593		/* сохраняем состояния body */
4594		_this.saveElStates = {
4595			bodyTop :       $( 'body' ).scrollTop(),
4596			bodyLeft :      $( 'body' ).scrollLeft(),
4597			htmlTop :       $( 'html' ).scrollTop(),
4598			htmlLeft :      $( 'html' ).scrollLeft(),
4599			bodyOverflow :  $( 'body' ).css( 'overflow' )
4600		};
4601		/* выставляем параметры на слой данных */
4602		_this.setStyle( _this.$page.addClass( _this.modeBlur ),{
4603			'position' : 'fixed',
4604			'top' : -( _this.saveElStates.bodyTop + _this.saveElStates.htmlTop ),
4605			'left' : -( _this.saveElStates.bodyLeft + _this.saveElStates.htmlLeft )
4606		});
4607		/* выставляем прокрутку страницы на ноль, показываем слой просмотра фото и образмериваем его */
4608		_this.setStyle( $( 'body' ).addClass( _this.modPhotoviewOpen ).scrollTop( 0 ),{
4609			'overflow' : 'visible'
4610		});
4611		_this.setStyle( _this.$el,{
4612			'display' : 'block'
4613		});
4614		_this.visibilityEl();
4615		_this.setPhotoviewHeight();
4616		_this.setImages();
4617		_this.states.widgetOpen = true;
4618		_this.storeCheck( 'open' );
4619		//  EVENT с клавиатуры "prev-37", "next-39" и "esc-27"
4620		$( 'body' ).on( 'keydown.photoview' , function( e ){
4621			_this.keyDownNavigate( e );
4622		});
4623	},
4624	/** close photo view */
4625	close: function(){
4626		var _this = this;
4627		if ( _this.visibleView() ){
4628			// скрываем фотовью
4629			_this.setStyle( _this.$el.hide(), {
4630				'position' : 'absolute'
4631			});
4632			// удаление урлов и стилей картинокс фотовью
4633			_this.cleaning();
4634			// выставляем прокрутку контентной части как было, задержка если из history
4635			var historyTimeout = _this.states.storeFromHistory ? 5 : 0;
4636			setTimeout( function () {
4637				// убираем класс размытия с контентной части и позиционируем
4638				_this.setStyle( _this.$page.removeClass( _this.modeBlur ),{
4639					'position' : 'relative',
4640					'top' : 0,
4641					'left' : 0
4642				});
4643				_this.setStyle( $( 'body' ).removeClass( _this.modPhotoviewOpe
4643n ), {
4644					'overflow': _this.saveElStates.bodyOverflow
4645				});
4646				$( 'body' )
4647					.scrollTop( _this.saveElStates.bodyTop )
4648					.scrollLeft( _this.saveElStates.bodyLeft );
4649				$( 'html' )
4650					.scrollTop( _this.saveElStates.htmlTop )
4651					.scrollLeft( _this.saveElStates.htmlLeft );
4652			}, historyTimeout );
4653			// передача в хистори нового хеша
4654			_this.storeCheck( 'close' );
4655			// состояние что фотовью не открыто
4656			_this.states.widgetOpen = false;
4657			// убираем обработку надатия клавиш
4658			$('body').off( 'keydown.photoview' );
4659		}
4660	},
4661	/** remove src and style images attribute, remove style sub blocks images */
4662	cleaning: function(){
4663		$( this.classPrefix + 'img', this.$el ).removeAttr( 'src' ).removeAttr( 'style' );
4664		this.$sub.removeAttr( 'style' );
4665	},
4666	/**
4667	 * обновляем получаем набор элементов по <groupID>, кол-во элементов и устанавливаем или скрываем номер активного
4668	 * update image items group
4669	 * @param {Object|Number} object params or group id
4670	 * @update {Number} this.group.id - group number
4671	 * @update {Object} this.group.$items - group items
4672	 * @update {Number} this.group.length - group length
4673	 * @add {Number} store number
4674	 */
4675	updateItemsGroup: function( params ){
4676		var _this = this;
4677		// обнуляем информацию об открытой группе
4678		_this.group.$items = false;
4679		_this.group.length = false;
4680		// определяем id группы
4681		if ( $.isPlainObject( params ) && typeof params.clickObj == "object" ){
4682			_this.group.id = params.clickObj.attr( 'data-'+_this.dataGroup ) || false;
4683		} else {
4684			_this.group.id = params.group;
4685		}
4686		// создаем набор объектов
4687		if ( _this.group.id === false && typeof params.clickObj == "object" ){
4688			_this.group.$items = params.clickObj;
4689		} else if ( _this.group.id ){
4690			_this.group.$items = $( _this.classPrefix + 'open[data-' + _this.dataGroup + '="' + _this.group.id + '"][data-' + _this.dataSrc + ']', $('body') ).filter(function () {
4691				return !$( this ).closest( ".the-in-carousel__item" ).hasClass("m-clone")
4692				// return !$( this ).closest( ".m-cloned" ).length;  // фильтрация клонированных элементов
4693			});
4694		}
4695		// Добавляем в объект имя картинки для хеша
4696		$.each( _this.group.$items, function( i, v ){
4697			this.photoViewWidget_photo =  $( v ).data( _this.dataImageId ) || $( v ).data( _this.dataSrc ).match(/.*\/([^\.]+?)\.[a-zA-Z]+$/)[ 1 ]; // имя картинки для хеша
4698		});
4699		// записываем кол-во элеметов в наборе
4700		_this.group.length = _this.group.$items.length
4701	},
4702	/** Получаем набор данных по слайдам: предыдущий, активный, следующий  */
4703	getItemsData: function( n ){
4704		var _this = this;
4705		if ( typeof n === 'number' ) _this.itemActive.index = n;
4706		_this.getOneItemData( 'itemActive', _this.itemActive.index );
4707		// определяем номер предыдущего элемента
4708		if (_this.itemActive.index > 0){
4709			_this.itemPrev.index = _this.itemActive.index - 1;
4710		} else if ( _this.settings.loopItems && _this.itemActive.index == 0 && _this.group.length > 1 ){
4711			_this.itemPrev.index = _this.group.length - 1;
4712		} else {
4713			_this.itemPrev.index = false;
4714		}
4715		_this.getOneItemData( 'itemPrev', _this.itemPrev.index );
4716		// определяем номер следующего элемента
4717		if ( _this.itemActive.index + 1 < _this.group.length ){
4718			_this.itemNext.index = _this.itemActive.index + 1;
4719		} else if ( _this.settings.loopItems && _this.itemActive.index + 1 == _this.group.length && _this.group.length > 1 ){
4720			_this.itemNext.index = 0;
4721		} else {
4722			_this.itemNext.index = false;
4723		}
4724		_this.getOneItemData('itemNext', _this.itemNext.index );
4725	},
4726	/** Запись набора данных по слайду */
4727	getOneItemData: function( name, index ){
4728		var _this = this;
4729		if ( index === false ){
4730			_this[ name ].$obj = false;
4731			_this[ name ].src = false;
4732		} else {
4733			_this[ name ].$obj = $( _this.group.$items[ index ] );
4734			_this[ name ].src = _this[ name ].$obj.data( _this.dataSrc );
4735		}
4736	},
4737
4738	/** Загружаем картинки и устанавливаем в верстку */
4739	setImages: function(arrayItems){
4740		var _this = this,
4741			itemsName = [ 'itemActive', 'itemPrev', 'itemNext' ];
4742		if ( typeof arrayItems === 'object' ) itemsName = arrayItems;
4743		$.each( itemsName, function( i, v ){
4744			if ( _this[ v ].src !== false ) {
4745				var $img = $( _this.classPrefix + 'img', _this[ '$' + v ] ),    // ссылка на елемент
4746					$newImage = $( '<img src="' + _this[ v ].src + '">');
4747				$img.removeAttr('src');
4748				if ( _this.group.$items[ _this[ v ].index ].photoViewWidget_imgLoaded ) {
4749					/* TODO remove */ //console.log('Already uploaded ' + _this[ v ].index);
4750					$img.attr( 'src', _this[ v ].src );
4751					if ( v == 'itemActive' ) _this.setImagesAct();
4752				} else {
4753					var $loader = $( _this.classPrefix + 'loader', _this[ '$' + v ] );
4754					$loader.show();
4755					$newImage.on( 'load', function() {
4756						/* TODO remove */ //console.log('Images UPLOAD ' +_this[ v ].index + ' ' + _this[ v ].src);
4757						_this.group.$items[ _this[ v ].index ].photoViewWidget_imgLoaded = true;
4758						$img.attr( 'src', _this[ v ].src );
4759						$loader.hide();
4760						if ( v == 'itemActive' ) _this.setImagesAct();
4761					}).on( 'error', function() {
4762						console.log( 'PhotoViewWidget images ERROR ' + _this[ v ].src );
4763					});
4764				}
4765			}
4766		});
4767		_this.setItemIndexView();
4768	},
4769	setImagesAct: function(){
4770		var _this = this;
4771		_this.imageDataReset();
4772		_this.setActiveData();
4773		_this.updateShare();
4774		_this.updateDataSize( true );
4775	},
4776
4777	/** Active item data */
4778	setActiveData: function(){
4779		var _this = this,
4780			openInfo = _this.itemActive.$obj.find( _this.classPrefix + 'open-info > *');
4781		$.each( openInfo , function(){
4782			$( '.' + $( this ).attr( 'class' ), _this.$el ).html( $( this ).html() );
4783		});
4784	},
4785	/** update share link and share title */
4786	updateShare: function(){
4787		var $share = $( '.share', this.$placeSocial );
4788		if ( $share.length > 0 ) {
4789			$share.attr({
4790				'data-url': this.itemActive.$obj.data(this.dataShareLink) || location.href,
4791				'data-title': this.itemActive.$obj.data(this.dataShareTitle) || $('meta[ property="og:title" ]').attr("content") || $('head title').html(),
4792				'data-id': this.itemActive.$obj.data(this.dataShareId)
4793			});
4794		};
4795	},
4796	/** */
4797	updateDataSize: function( change ){
4798		if ( this.visibleView ) {
4799			var _this = this,
4800				destTextH = this.$descText.height(),
4801				descSizeH = this.$descSize.height();
4802			if ( destTextH > 0 ){
4803				// При смене слайда сворачиваем описани для нового
4804				if ( change ) _this.showDescMore( false , true );
4805				// показываем блок описания
4806				_this.activeDataVisible( true );
4807				// проверяем видимость кнопки more
4808				if ( destTextH <= descSizeH ) {
4809					_this.showDescMore( false, true );
4810					_this.$descMore.hide()
4811				} else {
4812					_this.$descMore.show();
4813				}
4814				// выставляем высоту описания
4815				_this.$descOver.stop().height( _this.$desc.hasClass( _this.modeOpen ) ? Math.min( destTextH, parseInt( _this.clientHeight * 0.4 ) ) : Math.min( destTextH, descSizeH ) )
4816			} else {
4817				_this.activeDataVisible( false );
4818			}
4819
4820
4821		}
4822	},
4823	/** Показ и скрытие блока описание */
4824	activeDataVisible: function( state ){
4825		this.$desc.toggleClass(  this.modeDisabled, ( ( state === true ) ? false : true ) );
4826	},
4827	/** клик по кнопке показать больше описания */
4828	showDescMore: function( state, fast ){
4829		var _this = this,
4830			destTextH = _this.$descText.height(),
4831			descSizeH = _this.$descSize.height();
4832		if ( state !== false && state !== true ) {
4833			state = _this.$desc.hasClass( _this.modeOpen ) ? false : true;
4834		}
4835		_this.$descOver.stop().animate({
4836			height: state ? Math.min( destTextH, parseInt( _this.clientHeight * 0.4 ) ) : Math.min( destTextH, descSizeH )
4837		}, fast ? 0 : 250, function(){
4838			if ( state === true ) _this.$desc.toggleClass( _this.modeOpen, state );
4839		});
4840		if ( state === false ) _this.$desc.toggleClass( _this.modeOpen, state );
4841		_this.$descOver.scrollTop( 0 );
4842		if (  _this.$descOver.hasClass( 'the-in-scroll' ) ){
4843			_this.$descOver.trigger( 'scroll-to.the-in-scroll' );
4844		}
4845
4846	},
4847	/** CONTROL */
4848	controlsToggle: function( state ){
4849		var _this = this;
4850		if ( state === true ){
4851			_this.controlsShow();
4852		} else if ( state === false ){
4853			_this.controlsHide();
4854		} else {
4855			if( _this.states.visibleControls === true ){
4856				_this.controlsHide();
4857			} else {
4858				_this.controlsShow();
4859			}
4860		}
4861	},
4862	controlsHide: function(){
4863		var _this = this;
4864		_this.$canHide.stop().animate({
4865			opacity: 0
4866		}, 150, function(){
4867			_this.$canHide.addClass( _this.modeHidden );
4868			_this.states.visibleControls = false;
4869		});
4870	},
4871	controlsShow: function(){
4872		var _this = this;
4873		_this.$canHide.stop().animate({
4874			opacity: 1
4875		}, 150, function(){
4876			_this.$canHide.removeClass( _this.modeHidden );
4877			_this.states.visibleControls = true;
4878		});
4879	},
4880
4881	/** STORE */
4882	transferringFormat: function( obj, sign, sep ){
4883		var str='';
4884		sign = sign || '=';
4885		sep = sep || '&';
4886		if ( typeof obj === 'object' ) {
4887			$.each( obj, function ( i, v ) {
4888				if ( i != '' ) str += ( sep + i + ( v !== undefined ? sign + v : '' ) );
4889			});
4890			return str.replace( sep, '' );
4891		} else if ( typeof obj === 'string' ) {
4892			return obj
4893				.split( sep )
4894				.map( function( e ) { return e.split( sign ) } )
4895				.reduce( function ( o, arr ) { return o[ arr[ 0 ] ] = arr[ 1 ], o; }, {} );
4896		}
4897		return false;
4898	},
4899	storeUpdateUrl: function( stateObj, title, paramsObj, replace ){
4900		var _this = this;
4901		if ( _this.states.storeEnabled && !_this.states.storeFromHistory ){
4902			if ( replace ){
4903				history.replaceState( stateObj, title, _this.storeFormationUrl( paramsObj ) );
4904			} else {
4905				history.pushState( stateObj, title, _this.storeFormationUrl( paramsObj ) );
4906			}
4907		}
4908		_this.states.storeFromHistory = false;
4909	},
4910	storeFormationUrl: function( paramsObj ){
4911		var params = this.transferringFormat( paramsObj );
4912		return location.origin + location.pathname + location.search + ( ( params == '' || params === false ) ? '' : '#' + params );
4913	},
4914	storeUpdObjParams: function( objParams, state ){
4915		var _this = this;
4916		if ( state === false ){
4917			delete objParams[ _this.store.name ];
4918		} else {
4919			var objStoreParams = {};
4920			objStoreParams[ _this.store.group ] = _this.group.id;
4921			objStoreParams[ _this.store.photo ] = _this.group.$items[ _this.itemActive.index ].photoViewWidget_photo;
4922			objParams[ _this.store.name ] = _this.transferringFormat( objStoreParams, '%3D', '%2F' );
4923		}
4924		return objParams;
4925	},
4926	storeCheck: function( act ){
4927		var _this = this;
4928		if ( !_this.states.storeEnabled ) return false;
4929		var	objParams = _this.transferringFormat( location.hash.replace( '#', '' ) ),
4930			storeParams = objParams[_this.store.name] ? _this.transferringFormat(objParams[_this.store.name], '%3D', '%2F') : false;
4931		if ( act === 'close'){                                                              // Закрытие photoView
4932			_this.storeUpdateUrl( {}, null, _this.storeUpdObjParams( objParams, false ) );
4933		} else if ( act === 'open' ){                                                       // Открытие photoView
4934			_this.storeUpdateUrl( {}, null, _this.storeUpdObjParams( objParams ) );
4935		} else if ( act === 'change' ){                                                     // Переход на другой слайд photoView
4936			_this.storeUpdateUrl( {}, null, _this.storeUpdObjParams( objParams ), true );
4937		} else if ( !_this.states.widgetOpen && storeParams[ _this.store.group ] ){     // Открытие урла С параметром photo_view
4938			_this.open({
4939				group: storeParams[ _this.store.group ],
4940				photo: storeParams[ _this.store.photo ] || false
4941			});
4942		} else if ( !storeParams[ _this.store.group ] ){                                // Открытие урла БЕЗ параметра photo_view
4943			_this.close();
4944		}
4945	},
4946	storeHistory: function(){
4947		var _this = this;
4948		if ( _this.states.storeEnabled && !!( window.history && history.pushState && history.replaceState ) ){
4949			window.addEventListener( "popstate", function( e ) {
4950				_this.states.storeFromHistory = true;
4951				_this.storeCheck();
4952			}, false );
4953			// обработка story первый раз после загрузки страницы
4954			_this.storeCheck();
4955
4956		} else {
4957			_this.states.storeEnabled = false;
4958		}
4959	},
4960
4961	/** VISIBILITY BUTTONS (obj) */
4962
4963	/**
4964	 * видимость кнопок от ширины photoView и кол-ва фотографий
4965	 * visibility buttons
4966	 * @param {Obj | Array object }
4967	 */
4968	visibilityEl: function( el ){
4969		var _this = this;
4970		if ( _this.visibleView() ) {
4971			var objArr = _this.objArrCreate( el || _this.variableVisibility );
4972			if ( _this.group.length > 1 && ( !_this.states.hammerFunc || _this.settings.desktopWidth <= _this.getPhotoviewWidth() ) ) {
4973				_this.visibilityElAct( objArr, 'show' );
4974			} else {
4975				_this.visibilityElAct( objArr );
4976			}
4977		}
4978	},
4979	visibilityElAct: function( objArr, act ){
4980		if ( typeof objArr === 'object' && ( objArr instanceof Array ) ) {
4981			$.each( objArr, function ( k, v ) {
4982				act === 'show' ? v.show() : v.hide();
4983			});
4984		} else {
4985			act === 'show' ? objArr.show() : objArr.hide();
4986		}
4987	},
4988
4989	/**
4990	 * Следующий слайд
4991	 */
4992	changeNext: function(){
4993		this.changeItem( 'itemNext' );
4994	},
4995	/**
4996	 * Прердыдущий слайд
4997	 */
4998	changePrev: function(){
4999		this.changeItem( 'itemPrev' );
5000	},
5001	/**
5002	 * Прердыдущий слайд
5003	 * Changes slide
5004	 * @param {String} direction
5005	 */
5006	changeItem: function( dir ){
5007		var _this = this;
5008		if ( _this.states.itemChanges === false && _this[ dir ].index !== false ) {
5009			_this.states.itemChanges = true;
5010			_this.activeDataVisible( false );
5011			var sign = '';
5012			if ( dir === 'itemNext' ) sign = '-';
5013			_this.setStyle( _this.$sub, {
5014				'transition': {
5015					'prop': 'transform'
5016				},
5017				'transform': 'translate3d(' + sign + ( _this.getPhotoviewWidth() * 1.05 ) + 'px, 0px, 0px)',
5018				'overflow': 'visible'
5019			});
5020			_this.setStyle( _this.$itemActive, {
5021				'transition': {
5022					'prop': 'transform'
5023				},
5024				'transform': 'translate3d(' + sign + ( _this.getPhotoviewWidth() * 1.05 ) + 'px, 0px, 0px)'
5025			});
5026			// загружаем новые данные о слайдах
5027			_this.getItemsData( _this[ dir ].index);
5028			setTimeout( function() {
5029				// заменяем картинки на новые после окончания сдвига
5030				_this.setImages();
5031				// свдигаем слои назад
5032				_this.setStyle( _this.$sub, {
5033					'transition': {
5034						'prop': 'none'
5035					},
5036					'transform': 'translate3d(0px, 0px, 0px)',
5037					'overflow': 'hidden'
5038				});
5039				_this.setStyle( _this.$itemActive, {
5040					'transition': {
5041						'prop': 'none'
5042					},
5043					'transform': 'translate3d(0px, 0px, 0px)'
5044				});
5045				_this.states.itemChanges = false;
5046				_this.storeCheck( 'change' );
5047			}, _this.settings.durationTransition || 100 );
5048		}
5049	},
5050	/**
5051	 * управление с клавиатуры
5052	 * keydown navigate
5053	 * @param {Code}
5054	 * @param {Object}
5055	 * @returns {Boolean} true|false
5056	 */
5057	keyDownNavigate: function( e ){
5058		var _this = this;
5059		if( _this.visibleView() ){
5060			var	keyCode = {
5061				left: 37,   // button - Arrow Left
5062				right: 39,  // button - Arrow Right
5063				esc: 27     // button - Esc
5064			};
5065			switch ( e.keyCode ) {
5066				case keyCode.left:
5067					_this.changePrev();
5068					return true;
5069				case keyCode.right:
5070					_this.changeNext();
5071					return true;
5072				case keyCode.esc:
5073					_this.close();
5074					return true;
5075				default:
5076					return false;
5077			}
5078		}
5079	},
5080	/**
5081	 * устанавливает числа "номер слайда/общее кол-во"
5082	 * @returns {Boolean} true|false
5083	 */
5084	setItemIndexView: function(){
5085		var _this = this;
5086		if( _this.visibleView() ){
5087			if ( _this.group.length <= 1 ) {
5088				_this.$placeIndexView.hide();
5089				return false;
5090			} else {
5091				$( 'span', _this.$placeIndexView ).html( ( _this.itemActive.index + 1 ) + ' / ' + _this.group.length );
5092				_this.$placeIndexView.show();
5093				return true;
5094			}
5095		}
5096	},
5097	/**
5098	 * выставить высоту слоя просмотра фотографий равно высоте окна
5099	 * set the height of the photoview as a window
5100	 * @set {Number} value
5101	 * @returns {Boolean} true|false
5102	 */
5103	setPhotoviewHeight: function(){
5104		if( this.visibleView() ) {
5105			this.$el.height( this.clientHeight );
5106			return true;
5107		}
5108		return false;
5109	},
5110	/**
5111	 * получить ширину слоя просмотра фотографий
5112	 * get width photoview
5113	 * @returns {Number} value or {Boolean} false
5114	 */
5115	getPhotoviewWidth: function(){
5116		if( this.visibleView() ){
5117			return parseInt( this.$el.outerWidth() );
5118		}
5119		return false;
5120	},
5121	/**
5122	 * позиционирование контентной части по горизонтали при открытом окне фотовью
5123	 * position content to horizontal
5124	 * @set {Number} value
5125	 */
5126	posLayerLeft: function( $layer ){
5127		$layer = $layer || this.$page;
5128		if( this.visibleView() ) {
5129			this.saveElStates.bodyLeft = $( 'body' ).scrollLeft();
5130			this.saveElStates.htmlLeft = $( 'html' ).scrollLeft();
5131			$layer.css( 'left', '-' + ( this.saveElStates.bodyLeft + this.saveElStates.htmlLeft ) + 'px' );
5132		}
5133	},
5134	/**
5135	 * позиционирование контентной части по вертикали при открытом окне фотовью
5136	 * position content to vertical
5137	 * @set {Number} value
5138	 */
5139	posLayerTop: function( $layer ){
5140		$layer = $layer || this.$page;
5141		if( this.visibleView() && $layer.css( 'position' ) == 'absolute' ){
5142			var layerIndentTop = parseInt( $layer.css( 'top' ) ),           // top position layer content
5143				layerHeight = $layer.outerHeight();                         // layer content height
5144			if ( ( layerHeight + layerIndentTop ) < this.clientHeight && layerHeight > this.clientHeight ){
5145				this.saveElStates.bodyTop = layerHeight-this.clientHeight;
5146			} else if ( layerHeight < this.clientHeight ){
5147				this.saveElStates.bodyTop = 0;
5148			}
5149			$layer.css( 'top', '-' + this.saveElStates.bodyTop + 'px' );
5150		}
5151	},
5152	/**
5153	 * взять элемент по классу
5154	 * get live element by class name
5155	 * @param {String} selector
5156	 * @returns {Object}
5157	 */
5158	getBy: function( selector ) {
5159		return $( selector, this.$el );
5160	},
5161	/**
5162	 * видимость окна просмотра фотографий
5163	 * photoView visible
5164	 * @returns {Boolean} true|false
5165	 */
5166	visibleView: function(){
5167		return this.$el.is( ":visible" );
5168	},
5169	/**
5170	 * получение ширины клиента
5171	 * get clients width
5172	 * @returns {Number} value
5173	 */
5174	getCw: function(){
5175		return Math.max(window.innerWidth || 0, (document.getElementsByTagName('html')[0] || {}).clientWidth || 0)
5176	},
5177	/**
5178	 * получение высоты клиента
5179	 * get clients height
5180	 * @returns {Number} value
5181	 */
5182	getCh: function(){
5183		return Math.max(window.innerHeight || 0, (document.getElementsByTagName('html')[0] || {}
5183).clientHeight || 0)
5184	},
5185	/**
5186	 * установка стиля(ей) на объект
5187	 * set style to object
5188	 * @param {Object} obj
5189	 * @param {String | Object} property | states
5190	 * @param {String/Number | Object} value | states
5191	 */
5192	setStyle: function( obj, prop, val ){
5193		var _this = this;
5194		if ( typeof prop === 'object' ){
5195			$.each( prop, function( key, value ){
5196				_this.setStyle( obj, key, value );
5197			});
5198		} else if ( prop === 'transition' && typeof val === 'object' ){
5199			this.setStyleTransition( obj, val );
5200		} else {
5201			obj.css( _this.prefixedStyle( obj[ 0 ].style, prop ), val )
5202		}
5203	},
5204	/**
5205	 * установка стиля transition на объект
5206	 * set transition style to object
5207	 * @param {Object} obj
5208	 * @param {Object} states { prop, <time>, <type>, <delay> }
5209	 */
5210	setStyleTransition: function( obj, states ){
5211		var _this = this;
5212		if ( states.prop === 'none' ){
5213			obj.css( _this.prefixedStyle( obj[ 0 ].style, 'transition' ), 'none' );
5214		} else {
5215			var trDuration = ( states.duration || _this.settings.durationTransition || 100 ) + 'ms',
5216				trTiming = states.type || _this.settings.typeTransition || 'ease-out',
5217				trDelay = ( states.delay || '0' ) + 'ms';
5218			obj.css( _this.prefixedStyle( obj[ 0 ].style, 'transition' ), _this.prefixedStyle( obj[ 0 ].style, states.prop ) + ' ' + trDuration + ' ' + trTiming + ' ' + trDelay );
5219		}
5220	},
5221	/**
5222	 * получение префикса для значения свойства
5223	 * get the prefixed property
5224	 * @param {Object} obj
5225	 * @param {String} propert
5226	 * @returns {String | Undefined} prefixed
5227	 */
5228	prefixedStyle: function ( obj, property ) {
5229		var _this = this;
5230		var prefix, prop;
5231		var camelProp = property[ 0 ].toUpperCase() + property.slice( 1 );
5232		var i = 0;
5233		if ( !_this.vendor_prefixes ) _this.vendor_prefixes = [ '', 'webkit', 'Moz', 'MS', 'ms', 'o' ];
5234		while ( i < _this.vendor_prefixes.length ) {
5235			prefix = _this.vendor_prefixes[ i ];
5236			prop = ( prefix ) ? prefix + camelProp : property;
5237			if ( prop in obj ) {
5238				return prop;
5239			}
5240			i++;
5241		}
5242		return property;
5243	}
5244
5245};
5246
5247
5248;(function ( $, window, document, undefined ) {
5249
5250    var riaVictorina = function(el, options) {
5251        var project = '';
5252        // if (window.location.search.indexOf('project=ria2018') != -1) {
5253        //     project = '?project=ria2018';
5254        // }
5255        if (window.location.pathname.indexOf('editorial_preview') != -1) {
5256            project = '?preview=1';
5257        }
5258        var defaults = {
5259            actions: {
5260                getlast: '/services/victorins/get-last-question/'+project,
5261                addanswer: '/services/victorins/add-answer/'+project,
5262                getresults: '/services/victorins/get-results/'+project,
5263                reset: '/services/victorins/reset/'+project
5264            }
5265        };
5266        var _this = this;
5267        _this.el = $(el);
5268        _this.container = _this.el.find('.victorina__content');
5269        _this.question = _this.container.find('.victorina__question:last');
5270        _this.blitztimer = null;
5271        _this.defOptions = defaults;
5272        _this.userOptions = options;
5273        _this.options = $.extend(true, {}, defaults, options);
5274
5275        _this.init();
5276    };
5277
5278    riaVictorina.prototype = {
5279        init: function() {
5280            var _this = this;
5281            _this.article_id = _this.el.data('article-id');
5282            _this.victorina_id = _this.el.data('victorina-id');
5283            _this.rightanswers = 0;
5284
5285            if ( !_this.el.find('.victorina__cover').length ) {
5286                _this.resetVictorina(false);
5287            }
5288
5289            _this.el.on('click', '.victorina__submit button', function() {
5290                $(this).attr('disabled', 'disabled');
5291
5292                if ( $(this).parent().hasClass('m-victorina-next') ) {
5293                    _this.nextQuestion(true);
5294                } else if ( $(this).parent().hasClass('m-victorina-reset') ) {
5295                    _this.container.empty();
5296                    _this.resetVictorina(true);
5297                } else if ( $(this).parent().hasClass('m-victorina-start') ) {
5298                    // _this.el.find('.victorina__cover').addClass('m-hidden');
5299                    // _this.container.removeClass('m-hidden');
5300                    _this.resetVictorina(true);
5301                } else {
5302                    var ids = _this.question.find('form').serializeArray();
5303                    _this.addAnswer( ids );
5304                }
5305            });
5306            
5307            _this.setRect();
5308            window.addEventListener('resize', () => {
5309                _this.setRect();
5310            });
5311
5312        },
5313        setRect: function(){
5314            let getWidth = document.querySelector('.article__victorina').getBoundingClientRect().width.toFixed(0);
5315            getWidth = +getWidth;
5316            document.querySelectorAll('.victorina__answer-bg').forEach((el, i) => {
5317                if( getWidth >= 360 && getWidth <= 480){
5318                    el.style.width = getWidth + 'px';
5319                    el.style.height = (getWidth * 4 / 10).toFixed(0) + 'px';
5320                } else {
5321                    el.style.width = 100 + '%';
5322                    el.style.height = 157 + 'px';
5323                }
5324            });
5325        },
5326        nextQuestion: function(withscroll) {
5327            var _this = this;
5328
5329            _this.question.off('click', '.victorina__answer');
5330
5331            $.ajax({
5332                url: _this.options.actions.getlast,
5333                data: {
5334                    article_id: _this.article_id,
5335                    victorina_id: _this.victorina_id,
5336                    last_question_id: _this.question_id,
5337                    last_question_num: _this.question_num
5338                },
5339                dataType: 'html',
5340                type: 'POST'
5341            }).done(function(data) {
5342                if ( $(data).hasClass('victorina__result') ) {
5343                    _this.getResults();
5344                } else {
5345                    _this.container.append( data );
5346                    _this.question = _this.container.find('.victorina__question:last');
5347                    _this.initQuestion(withscroll);
5348                }
5349            });
5350        },
5351        addAnswer: function(data) {
5352            var _this = this;
5353
5354            data.push({ name: 'victorina_id', value: _this.victorina_id });
5355            data.push({ name: 'article_id', value: _this.article_id });
5356            data.push({ name: 'vic_question_id', value: _this.question_id });
5357
5358            $.ajax({
5359                url: _this.options.actions.addanswer,
5360                data: data,
5361                dataType: 'json',
5362                type: 'POST'
5363            }).done(function(data) {
5364                _this.showResult(data);
5365            });
5366        },
5367        getResults: function() {
5368            var _this = this;
5369            var data = {
5370                victorina_id: _this.victorina_id,
5371                rightanswers: _this.rightanswers
5372            }
5373            if (typeof _this.article_id !== 'undefined') {
5374                data.article_id = _this.article_id
5375            }
5376            clearInterval( _this.blitztimer );
5377            $.ajax({
5378                url: _this.options.actions.getresults,
5379                data: data,
5380                dataType: 'html',
5381                type: 'POST',
5382                success: function(data) {
5383                    var els = _this.container.append( data );
5384                    riaShare.initItems( els.find('.victorina__share') );
5385                    $('html, body').animate({
5386                        scrollTop: _this.container.find('.victorina__step:last').offset().top - 55
5387                    }, 300);
5388                }
5389            });
5390        },
5391        showResult: function(data) {
5392            var _this = this;
5393
5394            var header = _this.question.find('.victorina__question-header');
5395            header.find('.victorina__question-title').html( data.answer );
5396            if ( typeof data.incorrect !== 'undefined' ) {
5397                header.addClass('m-victorina-false');
5398            } else {
5399                header.addClass('m-victorina-true');
5400                _this.rightanswers++;
5401            }
5402
5403            _this.question.find('.victorina__answers').addClass('m-victorina-answers-results');
5404
5405            _this.question.find('.victorina__answer').each(function() {
5406                $(this).find('input').attr('disabled', 'disabled');
5407
5408                if ( typeof data["right_" + $(this).data('id')] !== 'undefined' ) {
5409                    $(this).addClass('m-victorina-true');
5410                    $(this).find('.victorina__answer-text').append('<div class="victorina__answer-annotation">' + data["right_" + $(this).data('id')] + '</div>');
5411                } else if ( typeof data["user_" + $(this).data('id')] !== 'undefined' ) {
5412                    $(this).addClass('m-victorina-false');
5413                    $(this).find('.victorina__answer-text').append('<div class="victorina__answer-annotation">' + data["user_" + $(this).data('id')] + '</div>');
5414                }
5415            });
5416
5417            _this.question.find('.victorina__submit').addClass('m-victorina-next').find('button').removeAttr('disabled').focus();
5418
5419        },
5420        resetVictorina: function(withscroll) {
5421            var _this = this;
5422
5423            $.ajax({
5424                url: _this.options.actions.reset,
5425                type: 'POST',
5426                data: {
5427                    victorina_id: _this.victorina_id
5428                }
5429            }).done(function() {
5430                delete _this.question_id;
5431                delete _this.question_num;
5432                _this.rightanswers = 0;
5433                if (!_this.el.find('.victorina__question').length) {
5434                    _this.nextQuestion(withscroll);
5435                } else {
5436                    _this.question = _this.container.find('.victorina__question:last');
5437                    _this.initQuestion(withscroll);
5438                }
5439            });
5440        },
5441        initQuestion: function(withscroll) {
5442            var _this = this;
5443            _this.question_id = _this.question.data('id');
5444            _this.question_num = _this.question.data('num');
5445
5446            _this.question.on('click', '.victorina__answer', function() {
5447                if ( _this.question.find('.victorina__answer-input input:checked').length ) {
5448                    _this.question.find('button').removeAttr('disabled');
5449                } else {
5450                    _this.question.find('button').attr('disabled', 'disabled');
5451                }
5452            });
5453
5454            if ( _this.container.attr('data-first-question') ) {
5455                var arr = ('' + _this.container.attr('data-first-question') ).split(',');
5456                _this.container.removeAttr('data-first-question');
5457
5458                for (var i = 0; i < arr.length; i++) {
5459                    _this.question.find('.victorina__answer-input input[value="' + arr[i] + '"]').attr('checked', 'checked');
5460                }
5461                var ids = _this.question.find('form').serializeArray();
5462                _this.addAnswer( ids );
5463            }
5464
5465            if ( _this.el.data('blitz-time') > 0 ) {
5466                _this.initBlitz();
5467            }
5468
5469            if (withscroll) {
5470                $('html, body').animate({
5471                    scrollTop: _this.container.find('.victorina__step:last').offset().top - 55
5472                }, 300);
5473            }
5474            riaShare.initItems(_this.question.find('.elem-info'));
5475
5476            ria.convertDate();
5477        },
5478        initBlitz: function(callback) {
5479            var _this = this;
5480            _this.question.find('.victorina__progress').append('<div class="victorina__progress-timer"></div>');
5481
5482            if ( _this.container.find('.victorina__question').length == 1 ) {
5483                var timer = _this.el.data('blitz-time'),
5484                    minutes,
5485                    seconds;
5486                _this.blitztimer = setInterval(function() {
5487                    minutes = parseInt(timer / 60, 10);
5488                    seconds = parseInt(timer % 60, 10);
5489                    minutes = minutes < 10 ? "0" + minutes : minutes;
5490                    seconds = seconds < 10 ? "0" + seconds : seconds;
5491
5492                    _this.container.find('.victorina__progress-timer').text(minutes + ":" + seconds);
5493
5494                    if (--timer < 0) {
5495                        _this.question.off('click', '.victorina__answer');
5496                        _this.question.find('.victorina__submit button').attr('disabled', 'disabled');
5497                        _this.getResults();
5498                    }
5499                }, 1000);
5500            }
5501        }
5502    };
5503
5504
5505    $.fn.riaVictorina = function(options) {
5506        return this.each(function(){
5507            if(!$.data(this, 'riaVictorina')) {
5508                $.data(this, 'riaVictorina', new riaVictorina(this, options));
5509            }
5510        });
5511    };
5512
5513    
5514
5515})( jQuery, window, document );
5516
5517/* sockjs-client v1.1.4 | http://sockjs.org | MIT license */
5518!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.SockJS=t()}}(function(){var t;return function t(e,n,r){function i(s,a){if(!n[s]){if(!e[s]){var l="function"==typeof require&&require;if(!a&&l)return l(s,!0);if(o)return o(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}
5518var c=n[s]={exports:{}};e[s][0].call(c.exports,function(t){var n=e[s][1][t];return i(n||t)},c,c.exports,t,e,n,r)}return n[s].exports}for(var o="function"==typeof require&&require,s=0;s<r.length;s++)i(r[s]);return i}({1:[function(t,e,n){(function(n){"use strict";var r=t("./transport-list");e.exports=t("./main")(r),"_sockjs_onload"in n&&setTimeout(n._sockjs_onload,1)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./main":14,"./transport-list":16}],2:[function(t,e,n){"use strict";function r(){o.call(this),this.initEvent("close",!1,!1),this.wasClean=!1,this.code=0,this.reason=""}var i=t("inherits"),o=t("./event");i(r,o),e.exports=r},{"./event":4,"inherits":54}],3:[function(t,e,n){"use strict";function r(){o.call(this)}var i=t("inherits"),o=t("./eventtarget");i(r,o),r.prototype.removeAllListeners=function(t){t?delete this._listeners[t]:this._listeners={}},r.prototype.once=function(t,e){function n(){r.removeListener(t,n),i||(i=!0,e.apply(this,arguments))}var r=this,i=!1;this.on(t,n)},r.prototype.emit=function(){var t=arguments[0],e=this._listeners[t];if(e){for(var n=arguments.length,r=new Array(n-1),i=1;i<n;i++)r[i-1]=arguments[i];for(var o=0;o<e.length;o++)e[o].apply(this,r)}},r.prototype.on=r.prototype.addListener=o.prototype.addEventListener,r.prototype.removeListener=o.prototype.removeEventListener,e.exports.EventEmitter=r},{"./eventtarget":5,"inherits":54}],4:[function(t,e,n){"use strict";function r(t){this.type=t}r.prototype.initEvent=function(t,e,n){return this.type=t,this.bubbles=e,this.cancelable=n,this.timeStamp=+new Date,this},r.prototype.stopPropagation=function(){},r.prototype.preventDefault=function(){},r.CAPTURING_PHASE=1,r.AT_TARGET=2,r.BUBBLING_PHASE=3,e.exports=r},{}],5:[function(t,e,n){"use strict";function r(){this._listeners={}}r.prototype.addEventListener=function(t,e){t in this._listeners||(this._listeners[t]=[]);var n=this._listeners[t];-1===n.indexOf(e)&&(n=n.concat([e])),this._listeners[t]=n},r.prototype.removeEventListener=function(t,e){var n=this._listeners[t];if(n){var r=n.indexOf(e);return-1!==r?void(n.length>1?this._listeners[t]=n.slice(0,r).concat(n.slice(r+1)):delete this._listeners[t]):void 0}},r.prototype.dispatchEvent=function(){var t=arguments[0],e=t.type,n=1===arguments.length?[t]:Array.apply(null,arguments);if(this["on"+e]&&this["on"+e].apply(this,n),e in this._listeners)for(var r=this._listeners[e],i=0;i<r.length;i++)r[i].apply(this,n)},e.exports=r},{}],6:[function(t,e,n){"use strict";function r(t){o.call(this),this.initEvent("message",!1,!1),this.data=t}var i=t("inherits"),o=t("./event");i(r,o),e.exports=r},{"./event":4,"inherits":54}],7:[function(t,e,n){"use strict";function r(t){this._transport=t,t.on("message",this._transportMessage.bind(this)),t.on("close",this._transportClose.bind(this))}var i=t("json3"),o=t("./utils/iframe");r.prototype._transportClose=function(t,e){o.postMessage("c",i.str
5518ingify([t,e]))},r.prototype._transportMessage=function(t){o.postMessage("t",t)},r.prototype._send=function(t){this._transport.send(t)},r.prototype._close=function(){this._transport.close(),this._transport.removeAllListeners()},e.exports=r},{"./utils/iframe":47,"json3":55}],8:[function(t,e,n){"use strict";var r=t("./utils/url"),i=t("./utils/event"),o=t("json3"),s=t("./facade"),a=t("./info-iframe-receiver"),l=t("./utils/iframe"),u=t("./location");e.exports=function(t,e){var n={};e.forEach(function(t){t.facadeTransport&&(n[t.facadeTransport.transportName]=t.facadeTransport)}),n[a.transportName]=a;var c;t.bootstrap_iframe=function(){var e;l.currentWindowId=u.hash.slice(1);var a=function(i){if(i.source===parent&&(void 0===c&&(c=i.origin),i.origin===c)){var a;try{a=o.parse(i.data)}catch(t){return void i.data}if(a.windowId===l.currentWindowId)switch(a.type){case"s":var f;try{f=o.parse(a.data)}catch(t){a.data;break}var h=f[0],d=f[1],p=f[2],v=f[3];if(h!==t.version)throw new Error('Incompatible SockJS! Main site uses: "'+h+'", the iframe: "'+t.version+'".');if(!r.isOriginEqual(p,u.href)||!r.isOriginEqual(v,u.href))throw new Error("Can't connect to different domain from within an iframe. ("+u.href+", "+p+", "+v+")");e=new s(new n[d](p,v));break;case"m":e._send(a.data);break;case"c":e&&e._close(),e=null}}};i.attachEvent("message",a),l.postMessage("s")}}},{"./facade":7,"./info-iframe-receiver":10,"./location":13,"./utils/event":46,"./utils/iframe":47,"./utils/url":52,"debug":void 0,"json3":55}],9:[function(t,e,n){"use strict";function r(t,e){i.call(this);var n=this,r=+new Date;this.xo=new e("GET",t),this.xo.once("finish",function(t,e){var i,o;if(200===t){if(o=+new Date-r,e)try{i=s.parse(e)}catch(t){}a.isObject(i)||(i={})}n.emit("finish",i,o),n.removeAllListeners()})}var i=t("events").EventEmitter,o=t("inherits"),s=t("json3"),a=t("./utils/object");o(r,i),r.prototype.close=function(){this.removeAllListeners(),this.xo.close()},e.exports=r},{"./utils/object":49,"debug":void 0,"events":3,"inherits":54,"json3":55}],10:[function(t,e,n){"use strict";function r(t){var e=this;o.call(this),this.ir=new l(t,a),this.ir.once("finish",function(t,n){e.ir=null,e.emit("message",s.stringify([t,n]))})}var i=t("inherits"),o=t("events").EventEmitter,s=t("json3"),a=t("./transport/sender/xhr-local"),l=t("./info-ajax");i(r,o),r.transportName="iframe-info-receiver",r.prototype.close=function(){this.ir&&(this.ir.close(),this.ir=null),this.removeAllListeners()},e.exports=r},{"./info-ajax":9,"./transport/sender/xhr-local":37,"events":3,"inherits":54,"json3":55}],11:[function(t,e,n){(function(n){"use strict";function r(t,e){var r=this;i.call(this);var o=function(){var n=r.ifr=new l(u.transportName,e,t);n.once("message",function(t){if(t){var e;try{e=s.parse(t)}catch(t){return r.emit("finish"),void r.close()}var n=e[0],i=e[1];r.emit("finish",n,i)}r.close()}),n.once("close",function(){r.emit("finish"),r.close()})};n.document.body?o():a.attachEvent("load",o)}var i=t("events").EventEmitter,o=t("inherits"),s=t("json3"),a=t("./utils/event"),l=t("./transport/iframe"),u=t("./info-iframe-receiver");o(r,i),r.enabled=function(){return l.enabled()},r.prototype.close=function(){this.ifr&&this.ifr.close(),this.removeAllListeners(),this.ifr=null},e.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./info-iframe-receiver":10,"./transport/iframe":22,"./utils/event":46,"debug":void 0,"events":3,"inherits":54,"json3":55}],12:[function(t,e,n){"use strict";function r(t,e){var n=this;i.call(this),setTimeout(function(){n.doXhr(t,e)},0)}var i=t("events").EventEmitter,o=t("inherits"),s=t("./utils/url"),a=t("./transport/sender/xdr"),l=t("./transport/sender/xhr-cors"),u=t("./transport/sender/xhr-local"),c=t("./transport/sender/xhr-fake"),f=t("./info-iframe"),h=t("./info-ajax");o(r,i),r._getReceiver=function(t,e,n){return n.sameOrigin?new h(e,u):l.enabled?new h(e,l):a.enabled&&n.sameScheme?new h(e,a):f.enabled()?new f(t,e):new h(e,c)},r.prototype.doXhr=function(t,e){var n=this,i=s.addPath(t,"/info");
5518this.xo=r._getReceiver(t,i,e),this.timeoutRef=setTimeout(function(){n._cleanup(!1),n.emit("finish")},r.timeout),this.xo.once("finish",function(t,e){n._cleanup(!0),n.emit("finish",t,e)})},r.prototype._cleanup=function(t){clearTimeout(this.timeoutRef),this.timeoutRef=null,!t&&this.xo&&this.xo.close(),this.xo=null},r.prototype.close=function(){this.removeAllListeners(),this._cleanup(!1)},r.timeout=8e3,e.exports=r},{"./info-ajax":9,"./info-iframe":11,"./transport/sender/xdr":34,"./transport/sender/xhr-cors":35,"./transport/sender/xhr-fake":36,"./transport/sender/xhr-local":37,"./utils/url":52,"debug":void 0,"events":3,"inherits":54}],13:[function(t,e,n){(function(t){"use strict";e.exports=t.location||{origin:"http://localhost:80",protocol:"http",host:"localhost",port:80,href:"http://localhost/",hash:""}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],14:[function(t,e,n){(function(n){"use strict";function r(t,e,n){if(!(this instanceof r))return new r(t,e,n);if(arguments.length<1)throw new TypeError("Failed to construct 'SockJS: 1 argument required, but only 0 present");y.call(this),this.readyState=r.CONNECTING,this.extensions="",this.protocol="",n=n||{},n.protocols_whitelist&&m.warn("'protocols_whitelist' is DEPRECATED. Use 'transports' instead."),this._transportsWhitelist=n.transports,this._transportOptions=n.transportOptions||{};var i=n.sessionId||8;if("function"==typeof i)this._generateSessionId=i;else{if("number"!=typeof i)throw new TypeError("If sessionId is used in the options, it needs to be a number or a function.");this._generateSessionId=function(){return u.string(i)}}this._server=n.server||u.numberString(1e3);var o=new s(t);if(!o.host||!o.protocol)throw new SyntaxError("The URL '"+t+"' is invalid");if(o.hash)throw new SyntaxError("The URL must not contain a fragment");if("http:"!==o.protocol&&"https:"!==o.protocol)throw new SyntaxError("The URL's scheme must be either 'http:' or 'https:'. '"+o.protocol+"' is not allowed.");var a="https:"===o.protocol;if("https"===g.protocol&&!a)throw new Error("SecurityError: An insecure SockJS connection may not be initiated from a page loaded over HTTPS");e?Array.isArray(e)||(e=[e]):e=[];var l=e.sort();l.forEach(function(t,e){if(!t)throw new SyntaxError("The protocols entry '"+t+"' is invalid.");if(e<l.length-1&&t===l[e+1])throw new SyntaxError("The protocols entry '"+t+"' is duplicated.")});var c=f.getOrigin(g.href);this._origin=c?c.toLowerCase():null,o.set("pathname",o.pathname.replace(/\/+$/,"")),this.url=o.href,this.url,this._urlInfo={nullOrigin:!v.hasDomain(),sameOrigin:f.isOriginEqual(this.url,g.href),sameScheme:f.isSchemeEqual(this.url,g.href)},this._ir=new _(this.url,this._urlInfo),this._ir.once("finish",this._receiveInfo.bind(this))}function i(t){return 1e3===t||t>=3e3&&t<=4999}t("./shims");var o,s=t("url-parse"),a=t("inherits"),l=t("json3"),u=t("./utils/random"),c=t("./utils/escape"),f=t("./utils/url"),h=t("./utils/event"),d=t("./utils/transport"),p=t("./utils/object"),v=t("./utils/browser"),m=t("./utils/log"),b=t("./event/event"),y=t("./event/eventtarget"),g=t("./location"),w=t("./event/close"),x=t("./event/trans-message"),_=t("./info-receiver");a(r,y),r.prototype.close=function(t,e){if(t&&!i(t))throw new Error("InvalidAccessError: Invalid code");if(e&&e.length>123)throw new SyntaxError("reason argument has an invalid length");if(this.readyState!==r.CLOSING&&this.readyState!==r.CLOSED){this._close(t||1e3,e||"Normal closure",!0)}},r.prototype.send=function(t){if("string"!=typeof t&&(t=""+t),this.readyState===r.CONNECTING)throw new Error("InvalidStateError: The connection has not been established yet");this.readyState===r.OPEN&&this._transport.send(c.quote(t))},r.version=t("./version"),r.CONNECTING=0,r.OPEN=1,r.CLOSING=2,r.CLOSED=3,r.prototype._receiveInfo=function(t,e){if(this._ir=null,!t)return void this._close(1002,"Cannot connect to server");this._rto=this.countRTO(e),this._transUrl=t.base_url?t.base_url:this.url,t=p.extend(t,this._urlInfo);var n=o.filterToEnabled(this._transportsWhitelist,t);this._transports=n.main,this._transports.length,this._connect()},r.prototype._connect=function(){for(var t=this._transports.shift();t;t=this._transports.shift()){if(t.transportName,t.needBody&&(!n.document.body||void 0!==n.document.readyState&&"complete"!==n.document.readyState&&"interactive"!==n.document.readyState))return this._transports.unshift(t),void h.attachEvent("load",this._connect.bind(this));var e=this._rto*t.roundTrips||5e3;this._transportTimeoutId=setTimeout(this._transportTimeout.bind(this),e);var r=f.addPath(this._transUrl,"/"+this._server+"/"+this._generateSessionId()),i=this._transportOptions[t.transportName],o=new t(r,this._transUrl,i);return o.on("message",this._transportMessage.bind(this)),o.once("close",this._transportClose.bind(this)),o.transportName=t.transportName,void(this._transport=o)}this._close(2e3,"All transports failed",!1)},r.prototype._transportTimeout=function(){this.readyState===r.CONNECTING&&this._transportClose(2007,"Transport timed out")},r.prototype._transportMessage=function(t){var e,n=this,r=t.slice(0,1),i=t.slice(1);switch(r){case"o":return void this._open();case"h":return this.dispatchEvent(new b("heartbeat")),void this.transport}if(i)try{e=l.parse(i)}catch(t){}if(void 0!==e)switch(r){case"a":Array.isArray(e)&&e.forEach(function(t){n.transport,n.dispatchEvent(new x(t))});break;case"m":this.transport,this.dispatchEvent(new x(e));break;case"c":Array.isArray(e)&&2===e.length&&this._close(e[0],e[1],!0)}},r.prototype._transportClose=function(t,e){if(this.transport,this._transport&&(this._transport.removeAllListeners(),this._transport=null,this.transport=null),!i(t)&&2e3!==t&&this.readyState===r.CONNECTING)return void this._connect();this._close(t,e)},r.prototype._open=function(){this._transport.transportName,this.readyState,this.readyState===r.CONNECTING?(this._transportTimeoutId&&(clearTimeout(this._transportTimeoutId),this._transportTimeoutId=null),this.readyState=r.OPEN,this.transport=this._transport.transportName,this.dispatchEvent(new b("open")),this.transport):this._close(1006,"Server lost session")},r.prototype._close=function(t,e,n){this.transport,this.readyState;var i=!1;if(this._ir&&(i=!0,this._ir.close(),this._ir=null),this._transport&&(this._transport.close(),this._transport=null,this.transport=null),this.readyState===r.CLOSED)throw new Error("InvalidStateError: SockJS has already been closed");this.readyState=r.CLOSING,setTimeout(function(){this.readyState=r.CLOSED,i&&this.dispatchEvent(new b("error"));var o=new w("close");o.wasClean=n||!1,o.code=t||1e3,o.reason=e,this.dispatchEvent(o),this.onmessage=this.onclose
5518=this.onerror=null}.bind(this),0)},r.prototype.countRTO=function(t){return t>100?4*t:300+t},e.exports=function(e){return o=d(e),t("./iframe-bootstrap")(r,e),r}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./event/close":2,"./event/event":4,"./event/eventtarget":5,"./event/trans-message":6,"./iframe-bootstrap":8,"./info-receiver":12,"./location":13,"./shims":15,"./utils/browser":44,"./utils/escape":45,"./utils/event":46,"./utils/log":48,"./utils/object":49,"./utils/random":50,"./utils/transport":51,"./utils/url":52,"./version":53,"debug":void 0,"inherits":54,"json3":55,"url-parse":58}],15:[function(t,e,n){"use strict";function r(t){var e=+t;return e!==e?e=0:0!==e&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function i(t){return t>>>0}function o(){}var s,a=Array.prototype,l=Object.prototype,u=Function.prototype,c=String.prototype,f=a.slice,h=l.toString,d=function(t){return"[object Function]"===l.toString.call(t)},p=function(t){return"[object Array]"===h.call(t)},v=function(t){return"[object String]"===h.call(t)},m=Object.defineProperty&&function(){try{return Object.defineProperty({},"x",{}),!0}catch(t){return!1}}();s=m?function(t,e,n,r){!r&&e in t||Object.defineProperty(t,e,{configurable:!0,enumerable:!1,writable:!0,value:n})}:function(t,e,n,r){!r&&e in t||(t[e]=n)};var b=function(t,e,n){for(var r in e)l.hasOwnProperty.call(e,r)&&s(t,r,e[r],n)},y=function(t){if(null==t)throw new TypeError("can't convert "+t+" to object");return Object(t)};b(u,{bind:function(t){var e=this;if(!d(e))throw new TypeError("Function.prototype.bind called on incompatible "+e);for(var n=f.call(arguments,1),r=function(){if(this instanceof l){var r=e.apply(this,n.concat(f.call(arguments)));return Object(r)===r?r:this}return e.apply(t,n.concat(f.call(arguments)))},i=Math.max(0,e.length-n.length),s=[],a=0;a<i;a++)s.push("$"+a);var l=Function("binder","return function ("+s.join(",")+"){ return binder.apply(this, arguments); }")(r);return e.prototype&&(o.prototype=e.prototype,l.prototype=new o,o.prototype=null),l}}),b(Array,{isArray:p});var g=Object("a"),w="a"!==g[0]||!(0 in g);b(a,{forEach:function(t){var e=y(this),n=w&&v(this)?this.split(""):e,r=arguments[1],i=-1,o=n.length>>>0;if(!d(t))throw new TypeError;for(;++i<o;)i in n&&t.call(r,n[i],i,e)}},!function(t){var e=!0,n=!0;return t&&(t.call("foo",function(t,n,r){"object"!=typeof r&&(e=!1)}),t.call([1],function(){n="string"==typeof this},"x")),!!t&&e&&n}(a.forEach));var x=Array.prototype.indexOf&&-1!==[0,1].indexOf(1,2);b(a,{indexOf:function(t){var e=w&&v(this)?this.split(""):y(this),n=e.length>>>0;if(!n)return-1;var i=0;for(arguments.length>1&&(i=r(arguments[1])),i=i>=0?i:Math.max(0,n+i);i<n;i++)if(i in e&&e[i]===t)return i;return-1}},x);var _=c.split;2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||"t"==="tesst".split(/(s)*/)[1]||4!=="test".split(/(?:)/,-1).length||"".split(/.?/).length||".".split(/()()/).length>1?function(){var t=void 0===/()??/.exec("")[1];c.split=function(e,n){var r=this;if(void 0===e&&0===n)return[];if("[object RegExp]"!==h.call(e))return _.call(this,e,n);var o,s,l,u,c=[],f=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.extended?"x":"")+(e.sticky?"y":""),d=0;for(e=new RegExp(e.source,f+"g"),r+="",t||(o=new RegExp("^"+e.source+"$(?!\\s)",f)),n=void 0===n?-1>>>0:i(n);(s=e.exec(r))&&!((l=s.index+s[0].length)>d&&(c.push(r.slice(d,s.index)),!t&&s.length>1&&s[0].replace(o,function(){for(var t=1;t<arguments.length-2;t++)void 0===arguments[t]&&(s[t]=void 0)}),s.length>1&&s.index<r.length&&a.push.apply(c,s.slice(1)),u=s[0].length,d=l,c.length>=n));)e.lastIndex===s.index&&e.lastIndex++;return d===r.length?!u&&e.test("")||c.push(""):c.push(r.slice(d)),c.length>n?c.slice(0,n):c}}():"0".split(void 0,0).length&&(c.split=function(t,e){return void 0===t&&0===e?[]:_.call(this,t,e)});var E=c.substr,j="".substr&&"b"!=="0b".substr(-1);b(c,{substr:function(t,e){return E.call(this,t<0&&(t=this.length+t)<0?0:t,e)}},j)},{}],16:[function(t,e,n){"use strict";e.exports=[t("./transport/websocket"),t("./transport/xhr-streaming"),t("./transport/xdr-streaming"),t("./transport/eventsource"),t("./transport/lib/iframe-wrap")(t("./transport/eventsource")),t("./transport/htmlfile"),t("./transport/lib/iframe-wrap")(t("./transport/htmlfile")),t("./transport/xhr-polling"),t("./transport/xdr-polling"),t("./transport/lib/iframe-wrap")(t("./transport/xhr-polling")),t("./transport/jsonp-polling")]},{"./transport/eventsource":20,"./transport/htmlfile":21,"./transport/jsonp-polling":23,"./transport/lib/iframe-wrap":26,"./transport/websocket":38,"./transport/xdr-polling":39,"./transport/xdr-streaming":40,"./transport/xhr-polling":41,"./transport/xhr-streaming":42}],17:[function(t,e,n){(function(n){"use strict";function r(t,e,n,r){var o=this;i.call(this),setTimeout(function(){o._start(t,e,n,r)},0)}var i=t("events").EventEmitter,o=t("inherits"),s=t("../../utils/event"),a=t("../../utils/url"),l=n.XMLHttpRequest;o(r,i),r.prototype._start=function(t,e,n,i){var o=this;try{this.xhr=new l}catch(t){}
5518if(!this.xhr)return this.emit("finish",0,"no xhr support"),void this._cleanup();e=a.addQuery(e,"t="+ +new Date),this.unloadRef=s.unloadAdd(function(){o._cleanup(!0)});try{this.xhr.open(t,e,!0),this.timeout&&"timeout"in this.xhr&&(this.xhr.timeout=this.timeout,this.xhr.ontimeout=function(){o.emit("finish",0,""),o._cleanup(!1)})}catch(t){return this.emit("finish",0,""),void this._cleanup(!1)}if(i&&i.noCredentials||!r.supportsCORS||(this.xhr.withCredentials="true"),i&&i.headers)for(var u in i.headers)this.xhr.setRequestHeader(u,i.headers[u]);this.xhr.onreadystatechange=function(){if(o.xhr){var t,e,n=o.xhr;switch(n.readyState,n.readyState){case 3:try{e=n.status,t=n.responseText}catch(t){}1223===e&&(e=204),200===e&&t&&t.length>0&&o.emit("chunk",e,t);break;case 4:e=n.status,1223===e&&(e=204),12005!==e&&12029!==e||(e=0),n.responseText,o.emit("finish",e,n.responseText),o._cleanup(!1)}}};try{o.xhr.send(n)}catch(t){o.emit("finish",0,""),o._cleanup(!1)}},r.prototype._cleanup=function(t){if(this.xhr){if(this.removeAllListeners(),s.unloadDel(this.unloadRef),this.xhr.onreadystatechange=function(){},this.xhr.ontimeout&&(this.xhr.ontimeout=null),t)try{this.xhr.abort()}catch(t){}this.unloadRef=this.xhr=null}},r.prototype.close=function(){this._cleanup(!0)},r.enabled=!!l;var u=["Active"].concat("Object").join("X");!r.enabled&&u in n&&(l=function(){try{return new n[u]("Microsoft.XMLHTTP")}catch(t){return null}},r.enabled=!!new l);var c=!1;try{c="withCredentials"in new l}catch(t){}r.supportsCORS=c,e.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../../utils/event":46,"../../utils/url":52,"debug":void 0,"events":3,"inherits":54}],18:[function(t,e,n){(function(t){e.exports=t.EventSource}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],19:[function(t,e,n){(function(t){"use strict";var n=t.WebSocket||t.MozWebSocket;e.exports=n?function(t){return new n(t)}:void 0}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],20:[function(t,e,n){"use strict";function r(t){if(!r.enabled())throw new Error("Transport created when disabled");o.call(this,t,"/eventsource",s,a)}var i=t("inherits"),o=t("./lib/ajax-based"),s=t("./receiver/eventsource"),a=t("./sender/xhr-cors"),l=t("eventsource");i(r,o),r.enabled=function(){return!!l},r.transportName="eventsource",r.roundTrips=2,e.exports=r},{"./lib/ajax-based":24,"./receiver/eventsource":29,"./sender/xhr-cors":35,"eventsource":18,"inherits":54}],21:[function(t,e,n){"use strict";function r(t){if(!o.enabled)throw new Error("Transport created when disabled");a.call(this,t,"/htmlfile",o,s)}var i=t("inherits"),o=t("./receiver/htmlfile"),s=t("./sender/xhr-local"),a=t("./lib/ajax-based");i(r,a),r.enabled=function(t){return o.enabled&&t.sameOrigin},r.transportName="htmlfile",r.roundTrips=2,e.exports=r},{"./lib/ajax-based":24,"./receiver/htmlfile":30,"./sender/xhr-local":37,"inherits":54}],22:[function(t,e,n){"use strict";function r(t,e,n){if(!r.enabled())throw new Error("Transport created when disabled");s.call(this);var i=this;this.origin=l.getOrigin(n),this.baseUrl=n,this.transUrl=e,this.transport=t,this.windowId=f.string(8);var o=l.addPath(n,"/iframe.html")+"#"+this.windowId;this.iframeObj=u.createIframe(o,function(t){i.emit("close",1006,"Unable to load an iframe ("+t+")"),i.close()}),this.onmessageCallback=this._message.bind(this),c.attachEvent("message",this.onmessageCallback)}var i=t("inherits"),o=t("json3"),s=t("events").EventEmitter,a=t("../version"),l=t("../utils/url"),u=t("../utils/iframe"),c=t("../utils/event"),f=t("../utils/random");i(r,s),r.prototype.close=function(){if(this.removeAllListeners(),this.iframeObj){c.detachEvent("message",this.onmessageCallback);try{this.postMessage("c")}catch(t){}this.iframeObj.cleanup(),this.iframeObj=null,this.onmessageCallback=this.iframeObj=null}},r.prototype._message=function(t){if(t.data,!l.isOriginEqual(t.origin,this.origin))return t.origin,void this.origin;var e;try{e=o.parse(t.data)}catch(e){return void t.data}if(e.windowId!==this.windowId)return e.windowId,void this.windowId;switch(e.type){case"s":this.iframeObj.loaded(),this.postMessage("s",o.stringify([a,this.transport,this.transUrl,this.baseUrl]));break;
5518case"t":this.emit("message",e.data);break;case"c":var n;try{n=o.parse(e.data)}catch(t){return void e.data}this.emit("close",n[0],n[1]),this.close()}},r.prototype.postMessage=function(t,e){this.iframeObj.post(o.stringify({windowId:this.windowId,type:t,data:e||""}),this.origin)},r.prototype.send=function(t){this.postMessage("m",t)},r.enabled=function(){return u.iframeEnabled},r.transportName="iframe",r.roundTrips=2,e.exports=r},{"../utils/event":46,"../utils/iframe":47,"../utils/random":50,"../utils/url":52,"../version":53,"debug":void 0,"events":3,"inherits":54,"json3":55}],23:[function(t,e,n){(function(n){"use strict";function r(t){if(!r.enabled())throw new Error("Transport created when disabled");o.call(this,t,"/jsonp",a,s)}var i=t("inherits"),o=t("./lib/sender-receiver"),s=t("./receiver/jsonp"),a=t("./sender/jsonp");i(r,o),r.enabled=function(){return!!n.document},r.transportName="jsonp-polling",r.roundTrips=1,r.needBody=!0,e.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./lib/sender-receiver":28,"./receiver/jsonp":31,"./sender/jsonp":33,"inherits":54}],24:[function(t,e,n){"use strict";function r(t){return function(e,n,r){var i={};"string"==typeof n&&(i.headers={"Content-type":"text/plain"});var o=s.addPath(e,"/xhr_send"),a=new t("POST",o,n,i);return a.once("finish",function(t){if(a=null,200!==t&&204!==t)return r(new Error("http status "+t));r()}),function(){a.close(),a=null;var t=new Error("Aborted");t.code=1e3,r(t)}}}function i(t,e,n,i){a.call(this,t,e,r(i),n,i)}var o=t("inherits"),s=t("../../utils/url"),a=t("./sender-receiver");o(i,a),e.exports=i},{"../../utils/url":52,"./sender-receiver":28,"debug":void 0,"inherits":54}],25:[function(t,e,n){"use strict";function r(t,e){o.call(this),this.sendBuffer=[],this.sender=e,this.url=t}var i=t("inherits"),o=t("events").EventEmitter;i(r,o),r.prototype.send=function(t){this.sendBuffer.push(t),this.sendStop||this.sendSchedule()},r.prototype.sendScheduleWait=function(){var t,e=this;this.sendStop=function(){e.sendStop=null,clearTimeout(t)},t=setTimeout(function(){e.sendStop=null,e.sendSchedule()},25)},r.prototype.sendSchedule=function(){this.sendBuffer.length;var t=this;if(this.sendBuffer.length>0){var e="["+this.sendBuffer.join(",")+"]";this.sendStop=this.sender(this.url,e,function(e){t.sendStop=null,e?(t.emit("close",e.code||1006,"Sending error: "+e),t.close()):t.sendScheduleWait()}),this.sendBuffer=[]}},r.prototype._cleanup=function(){this.removeAllListeners()},r.prototype.close=function(){this._cleanup(),this.sendStop&&(this.sendStop(),this.sendStop=null)},e.exports=r},{"debug":void 0,"events":3,"inherits":54}],26:[function(t,e,n){(function(n){"use strict";var r=t("inherits"),i=t("../iframe"),o=t("../../utils/object");e.exports=function(t){function e(e,n){i.call(this,t.transportName,e,n)}return r(e,i),e.enabled=function(e,r){if(!n.document)return!1;var s=o.extend({},r);return s.sameOrigin=!0,t.enabled(s)&&i.enabled()},e.transportName="iframe-"+t.transportName,e.needBody=!0,e.roundTrips=i.roundTrips+t.roundTrips-1,e.facadeTransport=t,e}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../../utils/object":49,"../iframe":22,"inherits":54}],27:[function(t,e,n){"use strict";function r(t,e,n){o.call(this),this.Receiver=t,this.receiveUrl=e,this.AjaxObject=n,this._scheduleReceiver()}var i=t("inherits"),o=t("events").EventEmitter;i(r,o),r.prototype._scheduleReceiver=function(){var t=this,e=this.poll=new this.Receiver(this.receiveUrl,this.AjaxObject);e.on("message",function(e){t.emit("message",e)}),e.once("close",function(n,r){t.pollIsClosing,t.poll=e=null,t.pollIsClosing||("network"===r?t._scheduleReceiver():(t.emit("close",n||1006,r),t.removeAllListeners()))})},r.prototype.abort=function(){this.removeAllListeners(),this.pollIsClosing=!0,this.poll&&this.poll.abort()},e.exports=r},{"debug":void 0,"events":3,"inherits":54}],28:[function(t,e,n){"use strict";function r(t,e,n,r,i){var l=o.addPath(t,e),u=this;s.call(this,t,n),this.poll=new a(r,l,i),this.poll.on("message",function(t){u.emit("message",t)}),this.poll.once("close",function(t,e){u.poll=null,u.emit("close",t,e),u.close()})}var i=t("inherits"),o=t("../../utils/url"),s=t("./buffered-sender"),a=t("./polling");i(r,s),r.prototype.close=function(){s.prototype.close.call(this),this.removeAllListeners(),this.poll&&(this.poll.abort(),this.poll=null)},e.exports=r},{"../../utils/url":52,"./buffered-sender":25,"./polling":27,"debug":void 0,"inherits":54}],29:[function(t,e,n){"use strict";function r(t){o.call(this);var e=this,n=this.es=new s(t);n.onmessage=function(t){t.data,e.emit("message",decodeURI(t.data))},n.onerror=function(t){n.readyState;var r=2!==n.readyState?"network":"permanent";e._cleanup(),e._close(r)}}var i=t("inherits"),o=t("events").EventEmitter,s=t("eventsource");i(r,o),r.prototype.abort=function(){this._cleanup(),this._close("user")},r.prototype._cleanup=function(){var t=this.es;t&&(t.onmessage=t.onerror=null,t.close(),this.es=null)},r.prototype._close=function(t){var e=this;setTimeout(function(){e.emit("close",null,t),e.removeAllListeners()},200)},e.exports=r},{"debug":void 0,"events":3,"eventsource":18,"inherits":54}],30:[function(t,e,n){(function(n){"use strict";function r(t){a.call(this);var e=this;o.polluteGlobalNamespace(),this.id="a"+l.string(6),t=s.addQuery(t,"c="+decodeURIComponent(o.WPrefix+"."+this.id
5518)),r.htmlfileEnabled;var i=r.htmlfileEnabled?o.createHtmlfile:o.createIframe;n[o.WPrefix][this.id]={start:function(){e.iframeObj.loaded()},message:function(t){e.emit("message",t)},stop:function(){e._cleanup(),e._close("network")}},this.iframeObj=i(t,function(){e._cleanup(),e._close("permanent")})}var i=t("inherits"),o=t("../../utils/iframe"),s=t("../../utils/url"),a=t("events").EventEmitter,l=t("../../utils/random");i(r,a),r.prototype.abort=function(){this._cleanup(),this._close("user")},r.prototype._cleanup=function(){this.iframeObj&&(this.iframeObj.cleanup(),this.iframeObj=null),delete n[o.WPrefix][this.id]},r.prototype._close=function(t){this.emit("close",null,t),this.removeAllListeners()},r.htmlfileEnabled=!1;var u=["Active"].concat("Object").join("X");if(u in n)try{r.htmlfileEnabled=!!new n[u]("htmlfile")}catch(t){}r.enabled=r.htmlfileEnabled||o.iframeEnabled,e.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../../utils/iframe":47,"../../utils/random":50,"../../utils/url":52,"debug":void 0,"events":3,"inherits":54}],31:[function(t,e,n){(function(n){"use strict";function r(t){var e=this;u.call(this),i.polluteGlobalNamespace(),this.id="a"+o.string(6);var s=a.addQuery(t,"c="+encodeURIComponent(i.WPrefix+"."+this.id));n[i.WPrefix][this.id]=this._callback.bind(this),this._createScript(s),this.timeoutId=setTimeout(function(){e._abort(new Error("JSONP script loaded abnormally (timeout)"))},r.timeout)}var i=t("../../utils/iframe"),o=t("../../utils/random"),s=t("../../utils/browser"),a=t("../../utils/url"),l=t("inherits"),u=t("events").EventEmitter;l(r,u),r.prototype.abort=function(){if(n[i.WPrefix][this.id]){var t=new Error("JSONP user aborted read");t.code=1e3,this._abort(t)}},r.timeout=35e3,r.scriptErrorTimeout=1e3,r.prototype._callback=function(t){this._cleanup(),this.aborting||(t&&this.emit("message",t),this.emit("close",null,"network"),this.removeAllListeners())},r.prototype._abort=function(t){this._cleanup(),this.aborting=!0,this.emit("close",t.code,t.message),this.removeAllListeners()},r.prototype._cleanup=function(){if(clearTimeout(this.timeoutId),this.script2&&(this.script2.parentNode.removeChild(this.script2),this.script2=null),this.script){var t=this.script;t.parentNode.removeChild(t),t.onreadystatechange=t.onerror=t.onload=t.onclick=null,this.script=null}delete n[i.WPrefix][this.id]},r.prototype._scriptError=function(){var t=this;this.errorTimer||(this.errorTimer=setTimeout(function(){t.loadedOkay||t._abort(new Error("JSONP script loaded abnormally (onerror)"))},r.scriptErrorTimeout))},r.prototype._createScript=function(t){var e,r=this,i=this.script=n.document.createElement("script");if(i.id="a"+o.string(8),i.src=t,i.type="text/javascript",i.charset="UTF-8",i.onerror=this._scriptError.bind(this),i.onload=function(){
5519		r._abort(new Error("JSONP script loaded abnormally (onload)"))},i.onreadystatechange=function(){if(i.readyState,/loaded|closed/.test(i.readyState)){if(i&&i.htmlFor&&i.onclick){r.loadedOkay=!0;try{i.onclick()}catch(t){}}i&&r._abort(new Error("JSONP script loaded abnormally (onreadystatechange)"))}},void 0===i.async&&n.document.attachEvent)if(s.isOpera())e=this.script2=n.document.createElement("script"),e.text="try{var a = document.getElementById('"+i.id+"'); if(a)a.onerror();}catch(x){};",i.async=e.async=!1;else{try{i.htmlFor=i.id,i.event="onclick"}catch(t){}i.async=!0}void 0!==i.async&&(i.async=!0);var a=n.document.getElementsByTagName("head")[0];a.insertBefore(i,a.firstChild),e&&a.insertBefore(e,a.firstChild)},e.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../../utils/browser":44,"../../utils/iframe":47,"../../utils/random":50,"../../utils/url":52,"debug":void 0,"events":3,"inherits":54}],32:[function(t,e,n){"use strict";function r(t,e){o.call(this);var n=this;this.bufferPosition=0,this.xo=new e("POST",t,null),this.xo.on("chunk",this._chunkHandler.bind(this)),this.xo.once("finish",function(t,e){n._chunkHandler(t,e),n.xo=null;var r=200===t?"network":"permanent";n.emit("close",null,r),n._cleanup()})}var i=t("inherits"),o=t("events").EventEmitter;i(r,o),r.prototype._chunkHandler=function(t,e){if(200===t&&e)for(var n=-1;;this.bufferPosition+=n+1){var r=e.slice(this.bufferPosition);if(-1===(n=r.indexOf("\n")))break;var i=r.slice(0,n);
5519i&&this.emit("message",i)}},r.prototype._cleanup=function(){this.removeAllListeners()},r.prototype.abort=function(){this.xo&&(this.xo.close(),this.emit("close",null,"user"),this.xo=null),this._cleanup()},e.exports=r},{"debug":void 0,"events":3,"inherits":54}],33:[function(t,e,n){(function(n){"use strict";function r(t){try{return n.document.createElement('<iframe name="'+t+'">')}catch(r){var e=n.document.createElement("iframe");return e.name=t,e}}function i(){o=n.document.createElement("form"),o.style.display="none",o.style.position="absolute",o.method="POST",o.enctype="application/x-www-form-urlencoded",o.acceptCharset="UTF-8",s=n.document.createElement("textarea"),s.name="d",o.appendChild(s),n.document.body.appendChild(o)}var o,s,a=t("../../utils/random"),l=t("../../utils/url");e.exports=function(t,e,n){o||i();var u="a"+a.string(8);o.target=u,o.action=l.addQuery(l.addPath(t,"/jsonp_send"),"i="+u);var c=r(u);c.id=u,c.style.display="none",o.appendChild(c);try{s.value=e}catch(t){}o.submit();var f=function(t){c.onerror&&(c.onreadystatechange=c.onerror=c.onload=null,setTimeout(function(){c.parentNode.removeChild(c),c=null},500),s.value="",n(t))};return c.onerror=function(){f()},c.onload=function(){f()},c.onreadystatechange=function(t){c.readyState,"complete"===c.readyState&&f()},function(){f(new Error("Aborted"))}}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../../utils/random":50,"../../utils/url":52,"debug":void 0}],34:[function(t,e,n){(function(n){"use strict";function r(t,e,n){var r=this;i.call(this),setTimeout(function(){r._start(t,e,n)},0)}var i=t("events").EventEmitter,o=t("inherits"),s=t("../../utils/event"),a=t("../../utils/browser"),l=t("../../utils/url");o(r,i),r.prototype._start=function(t,e,r){var i=this,o=new n.XDomainRequest;e=l.addQuery(e,"t="+ +new Date),o.onerror=function(){i._error()},o.ontimeout=function(){i._error()},o.onprogress=function(){o.responseText,i.emit("chunk",200,o.responseText)},o.onload=function(){i.emit("finish",200,o.responseText),i._cleanup(!1)},this.xdr=o,this.unloadRef=s.unloadAdd(function(){i._cleanup(!0)});try{this.xdr.open(t,e),this.timeout&&(this.xdr.timeout=this.timeout),this.xdr.send(r)}catch(t){this._error()}},r.prototype._error=function(){this.emit("finish",0,""),this._cleanup(!1)},r.prototype._cleanup=function(t){if(this.xdr){if(this.removeAllListeners(),s.unloadDel(this.unloadRef),this.xdr.ontimeout=this.xdr.onerror=this.xdr.onprogress=this.xdr.onload=null,t)try{this.xdr.abort()}catch(t){}this.unloadRef=this.xdr=null}},r.prototype.close=function(){this._cleanup(!0)},r.enabled=!(!n.XDomainRequest||!a.hasDomain()),e.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../../utils/browser":44,"../../utils/event":46,"../../utils/url":52,"debug":void 0,"events":3,"inherits":54}],35:[function(t,e,n){"use strict";function r(t,e,n,r){o.call(this,t,e,n,r)}var i=t("inherits"),o=t("../driver/xhr");i(r,o),r.enabled=o.enabled&&o.supportsCORS,e.exports=r},{"../driver/xhr":17,"inherits":54}],36:[function(t,e,n){"use strict";function r(){var t=this;i.call(this),this.to=setTimeout(function(){t.emit("finish",200,"{}")},r.timeout)}var i=t("events").EventEmitter;t("inherits")(r,i),r.prototype.close=function(){clearTimeout(this.to)},r.timeout=2e3,e.exports=r},{"events":3,"inherits":54}],37:[function(t,e,n){"use strict";function r(t,e,n){o.call(this,t,e,n,{noCredentials:!0})}var i=t("inherits"),o=t("../driver/xhr");i(r,o),r.enabled=o.enabled,e.exports=r},{"../driver/xhr":17,"inherits":54}],38:[function(t,e,n){"use strict";function r(t,e,n){if(!r.enabled())throw new Error("Transport created when disabled");a.call(this);var s=this,u=o.addPath(t,"/websocket");u="https"===u.slice(0,5)?"wss"+u.slice(5):"ws"+u.slice(4),this.url=u,this.ws=new l(this.url,[],n),this.ws.onmessage=function(t){t.data,s.emit("message",t.data)},this.unloadRef=i.unloadAdd(function(){s.ws.close()}),this.ws.onclose=function(t){t.code,t.reason,s.emit("close",t.code,t.reason),s._cleanup()},this.ws.onerror=function(t){s.emit("close",1006,"WebSocket connection broken"),s._cleanup()}}var i=t("../utils/event"),o=t("../utils/url"),s=t("inherits"),a=t("events").EventEmitter,l=t("./driver/websocket");s(r,a),r.prototype.send=function(t){var e="["+t+"]";this.ws.send(e)},r.prototype.close=function(){var t=this.ws;this._cleanup(),t&&t.close()},r.prototype._cleanup=function(){var t=this.ws;t&&(t.onmessage=t.onclose=t.onerror=null),i.unloadDel(this.unloadRef),this.unloadRef=this.ws=null,this.removeAllListeners()},r.enabled=function(){return!!l},r.transportName="websocket",r.roundTrips=2,e.exports=r},{"../utils/event":46,"../utils/url":52,"./driver/websocket":19,"debug":void 0,"events":3,"inherits":54}],39:[function(t,e,n){"use strict";function r(t){if(!l.enabled)throw new Error("Transport created when disabled");o.call(this,t,"/xhr",a,l)}var i=t("inherits"),o=t("./lib/ajax-based"),s=t("./xdr-streaming"),a=t("./receiver/xhr"),l=t("./sender/xdr");i(r,o),r.enabled=s.enabled,r.transportName="xdr-polling",r.roundTrips=2,e.exports=r},{"./lib/ajax-based":24,"./receiver/xhr":32,"./sender/xdr":34,"./xdr-streaming":40,"inherits":54}],40:[function(t,e,n){"use strict";function r(t){if(!a.enabled)throw new Error("Transport created when disabled");o.call(this,t,"/xhr_streaming",s,a)}var i=t("inherits"),o=t("./lib/ajax-based"),s=t("./receiver/xhr"),a=t("./sender/xdr");i(r,o),r.enabled=function(t){return!t.cookie_needed&&!t.nullOrigin&&(a.enabled&&t.sameScheme)},r.transportName="xdr-streaming",r.roundTrips=2,e.exports=r},{"./lib/ajax-based":24,"./receiver/xhr":32,"./sender/xdr":34,"inherits":54}],41:[function(t,e,n){"use strict";function r(t){if(!l.enabled&&!a.enabled)throw new Error("Transport created when disabled");o.call(this,t,"/xhr",s,a)}var i=t("inherits"),o=t("./lib/ajax-based"),s=t("./receiver/xhr"),a=t("./sender/xhr-cors"),l=t("./sender/xhr-local");i(r,o),r.enabled=function(t){return!t.nullOrigin&&(!(!l.enabled||!t.sameOrigin)||a.enabled)},r.transportName="xhr-polling",r.roundTrips=2,e.exports=r},{"./lib/ajax-based":24,"./receiver/xhr":32,"./sender/xhr-cors":35,"./sender/xhr-local":37,"inherits":54}],42:[function(t,e,n){(function(n){"use strict";function r(t){if(!l.enabled&&!a.enabled)throw new Error("Transport created when disabled");o.call(this,t,"/xhr_streaming",s,a)}var i=t("inherits"),o=t("./lib/ajax-based"),s=t("./receiver/xhr"),a=t("./sender/xhr-cors"),l=t("./sender/xhr-local"),u=t("../utils/browser");i(r,o),r.enabled=function(t){return!t.nullOrigin&&(!u.isOpera()&&a.enabled)},r.transportName="xhr-streaming",r.roundTrips=2,r.needBody=!!n.document,e.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../utils/browser":44,"./lib/ajax-based":24,"./receiver/xhr":32,"./sender/xhr-cors":35,"./sender/xhr-local":37,"inherits":54}],43:[function(t,e,n){(function(t){"use strict";t.crypto&&t.crypto.getRandomValues?e.exports.randomBytes=function(e){var n=new Uint8Array(e);return t.crypto.getRandomValues(n),n}:e.exports.randomBytes=function(t){for(var e=new Array(t),n=0;n<t;
5519n++)e[n]=Math.floor(256*Math.random());return e}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],44:[function(t,e,n){(function(t){"use strict";e.exports={isOpera:function(){return t.navigator&&/opera/i.test(t.navigator.userAgent)},isKonqueror:function(){return t.navigator&&/konqueror/i.test(t.navigator.userAgent)},hasDomain:function(){if(!t.document)return!0;try{return!!t.document.domain}catch(t){return!1}}}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],45:[function(t,e,n){"use strict";var r,i=t("json3"),o=/[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g,s=function(t){var e,n={},r=[];for(e=0;e<65536;e++)r.push(String.fromCharCode(e));return t.lastIndex=0,r.join("").replace(t,function(t){return n[t]="\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4),""}),t.lastIndex=0,n};e.exports={quote:function(t){var e=i.stringify(t);return o.lastIndex=0,o.test(e)?(r||(r=s(o)),e.replace(o,function(t){return r[t]})):e}}},{"json3":55}],46:[function(t,e,n){(function(n){"use strict";var r=t("./random"),i={},o=!1,s=n.chrome&&n.chrome.app&&n.chrome.app.runtime;e.exports={attachEvent:function(t,e){void 0!==n.addEventListener?n.addEventListener(t,e,!1):n.document&&n.attachEvent&&(n.document.attachEvent("on"+t,e),n.attachEvent("on"+t,e))},detachEvent:function(t,e){void 0!==n.addEventListener?n.removeEventListener(t,e,!1):n.document&&n.detachEvent&&(n.document.detachEvent("on"+t,e),n.detachEvent("on"+t,e))},unloadAdd:function(t){if(s)return null;var e=r.string(8);return i[e]=t,o&&setTimeout(this.triggerUnloadCallbacks,0),e},unloadDel:function(t){t in i&&delete i[t]},triggerUnloadCallbacks:function(){for(var t in i)i[t](),delete i[t]}};var a=function(){o||(o=!0,e.exports.triggerUnloadCallbacks())};s||e.exports.attachEvent("unload",a)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./random":50}],47:[function(t,e,n){(function(n){"use strict";var r=t("./event"),i=t("json3"),o=t("./browser");e.exports={WPrefix:"_jp",currentWindowId:null,polluteGlobalNamespace:function(){e.exports.WPrefix in n||(n[e.exports.WPrefix]={})},postMessage:function(t,r){n.parent!==n&&n.parent.postMessage(i.stringify({windowId:e.exports.currentWindowId,type:t,data:r||""}),"*")},createIframe:function(t,e){var i,o,s=n.document.createElement("iframe"),a=function(){clearTimeout(i);try{s.onload=null}catch(t){}s.onerror=null},l=function(){s&&(a(),setTimeout(function(){s&&s.parentNode.removeChild(s),s=null},0),r.unloadDel(o))},u=function(t){s&&(l(),e(t))},c=function(t,e){try{setTimeout(function(){s&&s.contentWindow&&s.contentWindow.postMessage(t,e)},0)}catch(t){}};return s.src=t,s.style.display="none",s.style.position="absolute",s.onerror=function(){u("onerror")},s.onload=function(){clearTimeout(i),i=setTimeout(function(){u("onload timeout")},2e3)},n.document.body.appendChild(s),i=setTimeout(function(){u("timeout")},15e3),o=r.unloadAdd(l),{post:c,cleanup:l,loaded:a}},createHtmlfile:function(t,i){var o,s,a,l=["Active"].concat("Object").join("X"),u=new n[l]("htmlfile"),c=function(){clearTimeout(o),a.onerror=null},f=function(){u&&(c(),r.unloadDel(s),a.parentNode.removeChild(a),a=u=null,CollectGarbage())},h=function(t){u&&(f(),i(t))},d=function(t,e){try{setTimeout(function(){a&&a.contentWindow&&a.contentWindow.postMessage(t,e)},0)}catch(t){}};
5519u.open(),u.write('<html><script>document.domain="'+n.document.domain+'";<\/script></html>'),u.close(),u.parentWindow[e.exports.WPrefix]=n[e.exports.WPrefix];var p=u.createElement("div");return u.body.appendChild(p),a=u.createElement("iframe"),p.appendChild(a),a.src=t,a.onerror=function(){h("onerror")},o=setTimeout(function(){h("timeout")},15e3),s=r.unloadAdd(f),{post:d,cleanup:f,loaded:c}}},e.exports.iframeEnabled=!1,n.document&&(e.exports.iframeEnabled=("function"==typeof n.postMessage||"object"==typeof n.postMessage)&&!o.isKonqueror())}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./browser":44,"./event":46,"debug":void 0,"json3":55}],48:[function(t,e,n){(function(t){"use strict";var n={};["log","debug","warn"].forEach(function(e){var r;try{r=t.console&&t.console[e]&&t.console[e].apply}catch(t){}n[e]=r?function(){return t.console[e].apply(t.console,arguments)}:"log"===e?function(){}:n.log}),e.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],49:[function(t,e,n){"use strict";e.exports={isObject:function(t){var e=typeof t;return"function"===e||"object"===e&&!!t},extend:function(t){if(!this.isObject(t))return t;for(var e,n,r=1,i=arguments.length;r<i;r++){e=arguments[r];for(n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])}return t}}},{}],50:[function(t,e,n){"use strict";var r=t("crypto"),i="abcdefghijklmnopqrstuvwxyz012345";e.exports={string:function(t){for(var e=i.length,n=r.randomBytes(t),o=[],s=0;s<t;s++)o.push(i.substr(n[s]%e,1));return o.join("")},number:function(t){return Math.floor(Math.random()*t)},numberString:function(t){var e=(""+(t-1)).length;return(new Array(e+1).join("0")+this.number(t)).slice(-e)}}},{"crypto":43}],51:[function(t,e,n){"use strict";e.exports=function(t){return{filterToEnabled:function(e,n){var r={main:[],facade:[]};return e?"string"==typeof e&&(e=[e]):e=[],t.forEach(function(t){if(t&&("websocket"!==t.transportName||!1!==n.websocket))return e.length&&-1===e.indexOf(t.transportName)?void t.transportName:void(t.enabled(n)?(t.transportName,r.main.push(t),t.facadeTransport&&r.facade.push(t.facadeTransport)):t.transportName)}),r}}}},{"debug":void 0}],52:[function(t,e,n){"use strict";var r=t("url-parse");e.exports={getOrigin:function(t){if(!t)return null;var e=new r(t);if("file:"===e.protocol)return null;var n=e.port;return n||(n="https:"===e.protocol?"443":"80"),e.protocol+"//"+e.hostname+":"+n},isOriginEqual:function(t,e){var n=this.getOrigin(t)===this.getOrigin(e);return n},isSchemeEqual:function(t,e){return t.split(":")[0]===e.split(":")[0]},addPath:function(t,e){var n=t.split("?");return n[0]+e+(n[1]?"?"+n[1]:"")},addQuery:function(t,e){return t+(-1===t.indexOf("?")?"?"+e:"&"+e)}}},{"debug":void 0,"url-parse":58}],53:[function(t,e,n){e.exports="1.1.4"},{}],54:[function(t,e,n){"function"==typeof Object.create?e.exports=function(t,e){t.super_=e,t.prototype=Object.create(e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}})}:e.exports=function(t,e){t.super_=e;var n=function(){};n.prototype=e.prototype,t.prototype=new n,t.prototype.constructor=t}},{}],55:[function(e,n,r){(function(e){(function(){function i(t,e){function n(t){if(n[t]!==m)return n[t];var i;if("bug-string-char-index"==t)i="a"!="a"[0];else if("json"==t)i=n("json-stringify")&&n("json-parse");else{var s,a='{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';if("json-stringify"==t){var l=e.stringify,c="function"==typeof l&&g;if(c){(s=function(){return 1}).toJSON=s;try{c="0"===l(0)&&"0"===l(new r)&&'""'==l(new o)&&l(y)===m&&l(m)===m&&l()===m&&"1"===l(s)&&"[1]"==l([s])&&"[null]"==l([m])&&"null"==l(null)&&"[null,null,null]"==l([m,y,null])&&l({"a":[s,!0,!1,null,"\0\b\n\f\r\t"]})==a&&"1"===l(null,s)&&"[\n 1,\n 2\n]"==l([1,2],null,1)&&'"-271821-04-20T00:00:00.000Z"'==l(new u(-864e13))&&'"+275760-09-13T00:00:00.000Z"'==l(new u(864e13))&&'"-000001-01-01T00:00:00.000Z"'==l(new u(-621987552e5))&&'"1969-12-31T23:59:59.999Z"'==l(new u(-1))}catch(t){c=!1}}i=c}if("json-parse"==t){var f=e.parse;if("function"==typeof f)try{if(0===f("0")&&!f(!1)){s=f(a);var h=5==s.a.length&&1===s.a[0];if(h){try{h=!f('"\t"')}catch(t){}if(h)try{h=1!==f("01")}catch(t){}if(h)try{h=1!==f("1.")}catch(t){}}}}catch(t){h=!1}i=h}}return n[t]=!!i}t||(t=l.Object()),e||(e=l.Object());var r=t.Number||l.Number,o=t.String||l.String,a=t.Object||l.Object,u=t.Date||l.Date,c=t.SyntaxError||l.SyntaxError,f=t.TypeError||l.TypeError,h=t.Math||l.Math,d=t.JSON||l.JSON;"object"==typeof d&&d&&(e.stringify=d.stringify,e.parse=d.parse);var p,v,m,b=a.prototype,y=b.toString,g=new u(-0xc782b5b800cec);try{g=-109252==g.getUTCFullYear()&&0===g.getUTCMonth()&&1===g.getUTCDate()&&10==g.getUTCHours()&&37==g.getUTCMinutes()&&6==g.getUTCSeconds()&&708==g.getUTCMilliseconds()}catch(t){}if(!n("json")){var w=n("bug-string-char-index");if(!g)var x=h.floor,_=[0,31,59,90,120,151,181,212,243,273,304,334],E=function(t,e){return _[e]+365*(t-1970)+x((t-1969+(e=+(e>1)))/4)-x((t-1901+e)/100)+x((t-1601+e)/400)};if((p=b.hasOwnProperty)||(p=function(t){var e,n={};return(n.__proto__=null,n.__proto__={"toString":1},n).toString!=y?p=function(t){var e=this.__proto__,n=t in(this.__proto__=null,this);return this.__proto__=e,n}:(e=n.constructor,p=function(t){var n=(this.constructor||e).prototype;return t in this&&!(t in n&&this[t]===n[t])}),n=null,p.call(this,t)}),v=function(t,e){var n,r,i,o=0;(n=function(){this.valueOf=0}).prototype.valueOf=0,r=new n;for(i in r)p.call(r,i)&&o++;return n=r=null,o?v=2==o?function(t,e){var n,r={},i="[object Function]"==y.call(t);for(n in t)i&&"prototype"==n||p.call(r,n)||!(r[n]=1)||!p.call(t,n)||e(n)}:function(t,e){var n,r,i="[object Function]"==y.call(t);for(n in t)i&&"prototype"==n||!p.call(t,n)||(r="constructor"===n)||e(n);
5519(r||p.call(t,n="constructor"))&&e(n)}:(r=["valueOf","toString","toLocaleString","propertyIsEnumerable","isPrototypeOf","hasOwnProperty","constructor"],v=function(t,e){var n,i,o="[object Function]"==y.call(t),a=!o&&"function"!=typeof t.constructor&&s[typeof t.hasOwnProperty]&&t.hasOwnProperty||p;for(n in t)o&&"prototype"==n||!a.call(t,n)||e(n);for(i=r.length;n=r[--i];a.call(t,n)&&e(n));}),v(t,e)},!n("json-stringify")){var j={92:"\\\\",34:'\\"',8:"\\b",12:"\\f",10:"\\n",13:"\\r",9:"\\t"},S=function(t,e){return("000000"+(e||0)).slice(-t)},T=function(t){for(var e='"',n=0,r=t.length,i=!w||r>10,o=i&&(w?t.split(""):t);n<r;n++){var s=t.charCodeAt(n);switch(s){case 8:case 9:case 10:case 12:case 13:case 34:case 92:e+=j[s];break;default:if(s<32){e+="\\u00"+S(2,s.toString(16));break}e+=i?o[n]:t.charAt(n)}}return e+'"'},O=function(t,e,n,r,i,o,s){var a,l,u,c,h,d,b,g,w,_,j,C,N,A,k,I;try{a=e[t]}catch(t){}if("object"==typeof a&&a)if("[object Date]"!=(l=y.call(a))||p.call(a,"toJSON"))"function"==typeof a.toJSON&&("[object Number]"!=l&&"[object String]"!=l&&"[object Array]"!=l||p.call(a,"toJSON"))&&(a=a.toJSON(t));else if(a>-1/0&&a<1/0){if(E){for(h=x(a/864e5),u=x(h/365.2425)+1970-1;E(u+1,0)<=h;u++);for(c=x((h-E(u,0))/30.42);E(u,c+1)<=h;c++);h=1+h-E(u,c),d=(a%864e5+864e5)%864e5,b=x(d/36e5)%24,g=x(d/6e4)%60,w=x(d/1e3)%60,_=d%1e3}else u=a.getUTCFullYear(),c=a.getUTCMonth(),h=a.getUTCDate(),b=a.getUTCHours(),g=a.getUTCMinutes(),w=a.getUTCSeconds(),_=a.getUTCMilliseconds();a=(u<=0||u>=1e4?(u<0?"-":"+")+S(6,u<0?-u:u):S(4,u))+"-"+S(2,c+1)+"-"+S(2,h)+"T"+S(2,b)+":"+S(2,g)+":"+S(2,w)+"."+S(3,_)+"Z"}else a=null;if(n&&(a=n.call(e,t,a)),null===a)return"null";if("[object Boolean]"==(l=y.call(a)))return""+a;if("[object Number]"==l)return a>-1/0&&a<1/0?""+a:"null";if("[object String]"==l)return T(""+a);if("object"==typeof a){for(A=s.length;A--;)if(s[A]===a)throw f();if(s.push(a),j=[],k=o,o+=i,"[object Array]"==l){for(N=0,A=a.length;N<A;N++)C=O(N,a,n,r,i,o,s),j.push(C===m?"null":C);I=j.length?i?"[\n"+o+j.join(",\n"+o)+"\n"+k+"]":"["+j.join(",")+"]":"[]"}else v(r||a,function(t){var e=O(t,a,n,r,i,o,s);e!==m&&j.push(T(t)+":"+(i?" ":"")+e)}),I=j.length?i?"{\n"+o+j.join(",\n"+o)+"\n"+k+"}":"{"+j.join(",")+"}":"{}";return s.pop(),I}};e.stringify=function(t,e,n){var r,i,o,a;if(s[typeof e]&&e)if("[object Function]"==(a=y.call(e)))i=e;else if("[object Array]"==a){o={};for(var l,u=0,c=e.length;u<c;l=e[u++],("[object String]"==(a=y.call(l))||"[object Number]"==a)&&(o[l]=1));}if(n)if("[object Number]"==(a=y.call(n))){if((n-=n%1)>0)for(r="",n>10&&(n=10);r.length<n;r+=" ");}else"[object String]"==a&&(r=n.length<=10?n:n.slice(0,10));return O("",(l={},l[""]=t,l),i,o,r,"",[])}}if(!n("json-parse")){var C,N,A=o.fromCharCode,k={92:"\\",34:'"',47:"/",98:"\b",116:"\t",110:"\n",102:"\f",114:"\r"},I=function(){throw C=N=null,c()},P=function(){for(var t,e,n,r,i,o=N,s=o.length;C<s;)switch(i=o.charCodeAt(C)){case 9:case 10:case 13:case 32:C++;break;case 123:case 125:case 91:case 93:case 58:case 44:return t=w?o.charAt(C):o[C],C++,t;case 34:for(t="@",C++;C<s;)if((i=o.charCodeAt(C))<32)I();else if(92==i)switch(i=o.charCodeAt(++C)){case 92:case 34:case 47:case 98:case 116:case 110:case 102:case 114:t+=k[i],C++;break;case 117:for(e=++C,n=C+4;C<n;C++)(i=o.charCodeAt(C))>=48&&i<=57||i>=97&&i<=102||i>=65&&i<=70||I();t+=A("0x"+o.slice(e,C));break;default:I()}else{if(34==i)break;for(i=o.charCodeAt(C),e=C;i>=32&&92!=i&&34!=i;)i=o.charCodeAt(++C);t+=o.slice(e,C)}if(34==o.charCodeAt(C))return C++,t;I();default:if(e=C,45==i&&(r=!0,i=o.charCodeAt(++C)),i>=48&&i<=57){for(48==i&&(i=o.charCodeAt(C+1))>=48&&i<=57&&I(),r=!1;C<s&&(i=o.charCodeAt(C))>=48&&i<=57;C++);if(46==o.charCodeAt(C)){for(n=++C;n<s&&(i=o.charCodeAt(n))>=48&&i<=57;n++);n==C&&I(),C=n}if(101==(i=o.charCodeAt(C))||69==i){for(i=o.charCodeAt(++C),43!=i&&45!=i||C++,n=C;n<s&&(i=o.charCodeAt(n))>=48&&i<=57;n++);n==C&&I(),C=n}return+o.slice(e,C)}if(r&&I(),"true"==o.slice(C,C+4))return C+=4,!0;if("false"==o.slice(C,C+5))return C+=5,!1;if("null"==o.slice(C,C+4))return C+=4,null;I()}return"$"},L=function(t){var e,n;if("$"==t&&I(),"string"==typeof t){if("@"==(w?t.charAt(0):t[0]))return t.slice(1);if("["==t){for(e=[];"]"!=(t=P());n||(n=!0))n&&(","==t?"]"==(t=P())&&I():I()),","==t&&I(),e.push(L(t));return e}if("{"==t){for(e={};"}"!=(t=P());n||(n=!0))n&&(","==t?"}"==(t=P())&&I():I()),","!=t&&"string"==typeof t&&"@"==(w?t.charAt(0):t[0])&&":"==P()||I(),e[t.slice(1)]=L(P());return e}I()}return t},R=function(t,e,n){var r=U(t,e,n);r===m?delete t[e]:t[e]=r},U=function(t,e,n){var r,i=t[e];if("object"==typeof i&&i)if("[object Array]"==y.call(i))for(r=i.length;r--;)R(i,r,n);else v(i,function(t){R(i,t,n)});return n.call(t,e,i)};e.parse=function(t,e){var n,r;return C=0,N=""+t,n=L(P()),"$"!=P()&&I(),C=N=null,e&&"[object Function]"==y.call(e)?U((r={},r[""]=n,r),"",e):n}}}return e.runInContext=i,e}var o="function"==typeof t&&t.amd,s={"function":!0,"object":!0},a=s[typeof r]&&r&&!r.nodeType&&r,l=s[typeof window]&&window||this,u=a&&s[typeof n]&&n&&!n.nodeType&&"object"==typeof e&&e;if(!u||u.global!==u&&u.window!==u&&u.self!==u||(l=u),a&&!o)i(l,a);else{var c=l.JSON,f=l.JSON3,h=!1,d=i(l,l.JSON3={"noConflict":function(){return h||(h=!0,l.JSON=c,l.JSON3=f,c=f=null),d}});l.JSON={"parse":d.parse,"stringify":d.stringify}}o&&t(function(){return d})}).call(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],56:[function(t,e,n){"use strict";function r(t){for(var e,n=/([^=?&]+)=?([^&]*)/g,r={};e=n.exec(t);
5519r[decodeURIComponent(e[1])]=decodeURIComponent(e[2]));return r}function i(t,e){e=e||"";var n=[];"string"!=typeof e&&(e="?");for(var r in t)o.call(t,r)&&n.push(encodeURIComponent(r)+"="+encodeURIComponent(t[r]));return n.length?e+n.join("&"):""}var o=Object.prototype.hasOwnProperty;n.stringify=i,n.parse=r},{}],57:[function(t,e,n){"use strict";e.exports=function(t,e){if(e=e.split(":")[0],!(t=+t))return!1;switch(e){case"http":case"ws":return 80!==t;case"https":case"wss":return 443!==t;case"ftp":return 21!==t;case"gopher":return 70!==t;case"file":return!1}return 0!==t}},{}],58:[function(t,e,n){"use strict";function r(t){var e=f.exec(t);return{protocol:e[1]?e[1].toLowerCase():"",slashes:!!e[2],rest:e[3]}}function i(t,e){for(var n=(e||"/").split("/").slice(0,-1).concat(t.split("/")),r=n.length,i=n[r-1],o=!1,s=0;r--;)"."===n[r]?n.splice(r,1):".."===n[r]?(n.splice(r,1),s++):s&&(0===r&&(o=!0),n.splice(r,1),s--);return o&&n.unshift(""),"."!==i&&".."!==i||n.push(""),n.join("/")}function o(t,e,n){if(!(this instanceof o))return new o(t,e,n);var s,a,f,d,p,v,m=h.slice(),b=typeof e,y=this,g=0;for("object"!==b&&"string"!==b&&(n=e,e=null),n&&"function"!=typeof n&&(n=c.parse),e=u(e),a=r(t||""),s=!a.protocol&&!a.slashes,y.slashes=a.slashes||s&&e.slashes,y.protocol=a.protocol||e.protocol||"",t=a.rest,a.slashes||(m[2]=[/(.*)/,"pathname"]);g<m.length;g++)d=m[g],f=d[0],v=d[1],f!==f?y[v]=t:"string"==typeof f?~(p=t.indexOf(f))&&("number"==typeof d[2]?(y[v]=t.slice(0,p),t=t.slice(p+d[2])):(y[v]=t.slice(p),t=t.slice(0,p))):(p=f.exec(t))&&(y[v]=p[1],t=t.slice(0,p.index)),y[v]=y[v]||(s&&d[3]?e[v]||"":""),d[4]&&(y[v]=y[v].toLowerCase());n&&(y.query=n(y.query)),s&&e.slashes&&"/"!==y.pathname.charAt(0)&&(""!==y.pathname||""!==e.pathname)&&(y.pathname=i(y.pathname,e.pathname)),l(y.port,y.protocol)||(y.host=y.hostname,y.port=""),y.username=y.password="",y.auth&&(d=y.auth.split(":"),y.username=d[0]||"",y.password=d[1]||""),y.origin=y.protocol&&y.host&&"file:"!==y.protocol?y.protocol+"//"+y.host:"null",y.href=y.toString()}function s(t,e,n){var r=this;switch(t){case"query":"string"==typeof e&&e.length&&(e=(n||c.parse)(e)),r[t]=e;break;case"port":r[t]=e,l(e,r.protocol)?e&&(r.host=r.hostname+":"+e):(r.host=r.hostname,r[t]="");break;case"hostname":r[t]=e,r.port&&(e+=":"+r.port),r.host=e;break;case"host":r[t]=e,/:\d+$/.test(e)?(e=e.split(":"),r.port=e.pop(),r.hostname=e.join(":")):(r.hostname=e,r.port="");break;case"protocol":r.protocol=e.toLowerCase(),r.slashes=!n;break;case"pathname":r.pathname=e.length&&"/"!==e.charAt(0)?"/"+e:e;break;default:r[t]=e}for(var i=0;i<h.length;i++){var o=h[i];o[4]&&(r[o[1]]=r[o[1]].toLowerCase())}return r.origin=r.protocol&&r.host&&"file:"!==r.protocol?r.protocol+"//"+r.host:"null",r.href=r.toString(),r}function a(t){t&&"function"==typeof t||(t=c.stringify);var e,n=this,r=n.protocol;r&&":"!==r.charAt(r.length-1)&&(r+=":");var i=r+(n.slashes?"//":"");return n.username&&(i+=n.username,n.password&&(i+=":"+n.password),i+="@"),i+=n.host+n.pathname,e="object"==typeof n.query?t(n.query):n.query,e&&(i+="?"!==e.charAt(0)?"?"+e:e),n.hash&&(i+=n.hash),i}var l=t("requires-port"),u=t("./lolcation"),c=t("querystringify"),f=/^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i,h=[["#","hash"],["?","query"],["/","pathname"],["@","auth",1],[NaN,"host",void 0,1,1],[/:(\d+)$/,"port",void 0,1],[NaN,"hostname",void 0,1,1]];o.prototype={set:s,toString:a},o.extractProtocol=r,o.location=u,o.qs=c,e.exports=o},{"./lolcation":59,"querystringify":56,"requires-port":57}],59:[function(t,e,n){(function(n){"use strict";var r,i=/^[A-Za-z][A-Za-z0-9+-.]*:\/\//,o={hash:1,query:1};e.exports=function(e){e=e||n.location||{},r=r||t("./");var s,a={},l=typeof e;if("blob:"===e.protocol)a=new r(unescape(e.pathname),{});else if("string"===l){a=new r(e,{});for(s in o)delete a[s]}else if("object"===l){for(s in e)s in o||(a[s]=e[s]);void 0===a.slashes&&(a.slashes=i.test(e.href))}return a}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./":58}]},{},[1])(1)});
5520
5521var RIA_SOCK_DEFAULT_INTERVALS = [10000, 15000, 45000, 70000, 300000];
5522
5523var ria_sock = {
5524	events: {},
5525	instance: null,
5526	connected: false,
5527	connectionInterval: null,
5528	connectionIntervalTime: 30000,
5529	reconnectIntervals: RIA_SOCK_DEFAULT_INTERVALS.concat([]),
5530	url: GLOBAL.sock.server,
5531	on: function (eventName, fn) {
5532		this.events[eventName] = this.events[eventName] || [];
5533		this.events[eventName].push(fn);
5534	},
5535	off: function (eventName, fn) {
5536		if (this.events[eventName]) {
5537			for (var i = 0; i < this.events[eventName].length; i++) {
5538				if (this.events[eventName][i] === fn) {
5539					this.events[eventName].splice(i, 1);
5540					break;
5541				}
5542			};
5543		}
5544	},
5545	emit: function (eventName, data) {
5546		if (this.events[eventName]) {
5547			this.events[eventName].forEach(function (fn) {
5548				fn(data);
5549			});
5550		}
5551	},
5552	get: function() {
5553		return this.instance;
5554	},
5555	send: function(data) {
5556		data.message.lang = GLOBAL.sock.lang;
5557		data.message.project = GLOBAL.sock.project;
5558		this.instance && this.instance.send(JSON.stringify(data));
5559	},
5560	connect: function() {
5561		ria_sock.instance = new SockJS(ria_sock.url, null, {
5562			transports: ['websocket']
5563		});
5564	},
5565	reconnect: function() {
5566		if (!ria_sock.reconnectIntervals.length) {
5567			return;
5568		}
5569
5570		if (ria_sock.connected) {
5571			return;
5572		}
5573
5574		setTimeout(function() {
5575			ria_sock.init();
5576		}, ria_sock.reconnectIntervals.shift())
5577	},
5578	init: function() {
5579		if (!ria_sock.instance) {
5580			ria_sock.connect();
5581		}
5582
5583		this.instance.onmessage = function(e) {
5584			var data = JSON.parse(e.data);
5585			ria_sock.emit(data.type, data);
5586			ria_sock.emit('onmessage', e);
5587		}
5588
5589		this.instance.onopen = function() {
5590			if (ria_sock.connectionInterval) {
5591				clearInterval(ria_sock.connectionInterval)
5592			}
5593
5594			ria_sock.connected = true;
5595
5596			ria_sock.connectionInterval = setInterval(function() {
5597				ria_sock.reconnectIntervals = RIA_SOCK_DEFAULT_INTERVALS.concat([]);
5598				clearInterval(ria_sock.connectionInterval);
5599			}, ria_sock.connectionIntervalTime);
5600
5601			ria_sock.send({
5602				type: 'user_join',
5603				message: {
5604					user_id: GLOBAL.user.id || null,
5605					obj_id: (GLOBAL.article && GLOBAL.article.id) || (location.pathname === '/' ? 'main' : 'page')
5606				}
5607			});
5608
5609			ria_sock.emit('onopen');
5610		}
5611
5612		this.instance.onclose = function(e) {
5613			if (ria_sock.connectionInterval) {
5614				clearInterval(ria_sock.connectionInterval)
5615			}
5616
5617			ria_sock.connected = false;
5618
5619			ria_sock.instance = null;
5620			ria_sock.reconnect();
5621
5622			ria_sock.emit('onclose', e);
5623		}
5624
5625		this.instance.onerror = function(e) {
5626			console.error("Sock connection error", e);
5627			ria_sock.emit('onerror', e);
5628		}
5629	}
5630};
5631
5632if (GLOBAL.sock) {
5633	ria_sock.init();
5634}
5635/**
5636 * @license
5637 * Lodash lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
5638 */
5639;(function(){function n(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function t(n,t,r,e){for(var u=-1,i=null==n?0:n.length;++u<i;){var o=n[u];t(e,o,r(o),n)}return e}function r(n,t){for(var r=-1,e=null==n?0:n.length;++r<e&&false!==t(n[r],r,n););return n}function e(n,t){for(var r=null==n?0:n.length;r--&&false!==t(n[r],r,n););return n}function u(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(!t(n[r],r,n))return false;
5640    return true}function i(n,t){for(var r=-1,e=null==n?0:n.length,u=0,i=[];++r<e;){var o=n[r];t(o,r,n)&&(i[u++]=o)}return i}function o(n,t){return!(null==n||!n.length)&&-1<v(n,t,0)}function f(n,t,r){for(var e=-1,u=null==n?0:n.length;++e<u;)if(r(t,n[e]))return true;return false}function c(n,t){for(var r=-1,e=null==n?0:n.length,u=Array(e);++r<e;)u[r]=t(n[r],r,n);return u}function a(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function l(n,t,r,e){var u=-1,i=null==n?0:n.length;for(e&&i&&(r=n[++u]);++u<i;)r=t(r,n[u],u,n);
5641    return r}function s(n,t,r,e){var u=null==n?0:n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r}function h(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(t(n[r],r,n))return true;return false}function p(n,t,r){var e;return r(n,function(n,r,u){if(t(n,r,u))return e=r,false}),e}function _(n,t,r,e){var u=n.length;for(r+=e?1:-1;e?r--:++r<u;)if(t(n[r],r,n))return r;return-1}function v(n,t,r){if(t===t)n:{--r;for(var e=n.length;++r<e;)if(n[r]===t){n=r;break n}n=-1}else n=_(n,d,r);return n}function g(n,t,r,e){
5642    --r;for(var u=n.length;++r<u;)if(e(n[r],t))return r;return-1}function d(n){return n!==n}function y(n,t){var r=null==n?0:n.length;return r?m(n,t)/r:F}function b(n){return function(t){return null==t?T:t[n]}}function x(n){return function(t){return null==n?T:n[t]}}function j(n,t,r,e,u){return u(n,function(n,u,i){r=e?(e=false,n):t(r,n,u,i)}),r}function w(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function m(n,t){for(var r,e=-1,u=n.length;++e<u;){var i=t(n[e]);i!==T&&(r=r===T?i:r+i)}return r;
5643}function A(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function k(n,t){return c(t,function(t){return[t,n[t]]})}function E(n){return function(t){return n(t)}}function S(n,t){return c(t,function(t){return n[t]})}function O(n,t){return n.has(t)}function I(n,t){for(var r=-1,e=n.length;++r<e&&-1<v(t,n[r],0););return r}function R(n,t){for(var r=n.length;r--&&-1<v(t,n[r],0););return r}function z(n){return"\\"+Cn[n]}function W(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n];
5644}),r}function B(n,t){return function(r){return n(t(r))}}function L(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r];o!==t&&"__lodash_placeholder__"!==o||(n[r]="__lodash_placeholder__",i[u++]=r)}return i}function U(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=n}),r}function C(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=[n,n]}),r}function D(n){if(Rn.test(n)){for(var t=On.lastIndex=0;On.test(n);)++t;n=t}else n=Qn(n);return n}function M(n){return Rn.test(n)?n.match(On)||[]:n.split("");
5645}var T,$=1/0,F=NaN,N=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],P=/\b__p\+='';/g,Z=/\b(__p\+=)''\+/g,q=/(__e\(.*?\)|\b__t\))\+'';/g,V=/&(?:amp|lt|gt|quot|#39);/g,K=/[&<>"']/g,G=RegExp(V.source),H=RegExp(K.source),J=/<%-([\s\S]+?)%>/g,Y=/<%([\s\S]+?)%>/g,Q=/<%=([\s\S]+?)%>/g,X=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nn=/^\w*$/,tn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,rn=/[\\^$.*+?()[\]{}|]/g,en=RegExp(rn.source),un=/^\s+|\s+$/g,on=/^\s+/,fn=/\s+$/,cn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,an=/\{\n\/\* \[wrapped with (.+)\] \*/,ln=/,? & /,sn=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,hn=/\\(\\)?/g,pn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,_n=/\w*$/,vn=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,dn=/^\[object .+?Constructor\]$/,yn=/^0o[0-7]+$/i,bn=/^(?:0|[1-9]\d*)$/,xn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u01
56457f]/g,jn=/($^)/,wn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?)*",An="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,kn="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",En=RegExp("['\u2019]","g"),Sn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),On=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+kn+mn,"g"),In=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])|\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])|\\d+",An].join("|"),"g"),Rn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),zn=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Bn={};
5646    Bn["[object Float32Array]"]=Bn["[object Float64Array]"]=Bn["[object Int8Array]"]=Bn["[object Int16Array]"]=Bn["[object Int32Array]"]=Bn["[object Uint8Array]"]=Bn["[object Uint8ClampedArray]"]=Bn["[object Uint16Array]"]=Bn["[object Uint32Array]"]=true,Bn["[object Arguments]"]=Bn["[object Array]"]=Bn["[object ArrayBuffer]"]=Bn["[object Boolean]"]=Bn["[object DataView]"]=Bn["[object Date]"]=Bn["[object Error]"]=Bn["[object Function]"]=Bn["[object Map]"]=Bn["[object Number]"]=Bn["[object Object]"]=Bn["[object RegExp]"]=Bn["[object Set]"]=Bn["[object String]"]=Bn["[object WeakMap]"]=false;
5647    var Ln={};Ln["[object Arguments]"]=Ln["[object Array]"]=Ln["[object ArrayBuffer]"]=Ln["[object DataView]"]=Ln["[object Boolean]"]=Ln["[object Date]"]=Ln["[object Float32Array]"]=Ln["[object Float64Array]"]=Ln["[object Int8Array]"]=Ln["[object Int16Array]"]=Ln["[object Int32Array]"]=Ln["[object Map]"]=Ln["[object Number]"]=Ln["[object Object]"]=Ln["[object RegExp]"]=Ln["[object Set]"]=Ln["[object String]"]=Ln["[object Symbol]"]=Ln["[object Uint8Array]"]=Ln["[object Uint8ClampedArray]"]=Ln["[object Uint16Array]"]=Ln["[object Uint32Array]"]=true,
5648        Ln["[object Error]"]=Ln["[object Function]"]=Ln["[object WeakMap]"]=false;var Un,Cn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Dn=parseFloat,Mn=parseInt,Tn=typeof global=="object"&&global&&global.Object===Object&&global,$n=typeof self=="object"&&self&&self.Object===Object&&self,Fn=Tn||$n||Function("return this")(),Nn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Pn=Nn&&typeof module=="object"&&module&&!module.nodeType&&module,Zn=Pn&&Pn.exports===Nn,qn=Zn&&Tn.process;
5649    n:{try{Un=qn&&qn.binding&&qn.binding("util");break n}catch(n){}Un=void 0}var Vn=Un&&Un.isArrayBuffer,Kn=Un&&Un.isDate,Gn=Un&&Un.isMap,Hn=Un&&Un.isRegExp,Jn=Un&&Un.isSet,Yn=Un&&Un.isTypedArray,Qn=b("length"),Xn=x({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I",
5650        "\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C","\u0108":"C","\u010a":"C",
5651        "\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"
5651c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i","\u012b":"i","\u012d":"i",
5652        "\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r","\u015a":"S","\u015c":"S",
5653        "\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij","\u0152":"Oe","\u0153":"oe",
5654        "\u0149":"'n","\u017f":"s"}),nt=x({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}),tt=x({"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"}),rt=function x(mn){function An(n){if(du(n)&&!of(n)&&!(n instanceof Un)){if(n instanceof On)return n;if(ii.call(n,"__wrapped__"))return $e(n)}return new On(n)}function kn(){}function On(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=T}function Un(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,
5655        this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Cn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Tn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function $n(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Nn(n){var t=-1,r=null==n?0:n.length;for(this.__data__=new $n;++t<r;)this.add(n[t])}function Pn(n){
5656        this.size=(this.__data__=new Tn(n)).size}function qn(n,t){var r,e=of(n),u=!e&&uf(n),i=!e&&!u&&cf(n),o=!e&&!u&&!i&&pf(n),u=(e=e||u||i||o)?A(n.length,Xu):[],f=u.length;for(r in n)!t&&!ii.call(n,r)||e&&("length"==r||i&&("offset"==r||"parent"==r)||o&&("buffer"==r||"byteLength"==r||"byteOffset"==r)||Se(r,f))||u.push(r);return u}function Qn(n){var t=n.length;return t?n[ir(0,t-1)]:T}function et(n,t){return Ce(Ur(n),pt(t,0,n.length))}function ut(n){return Ce(Ur(n))}function it(n,t,r){(r===T||au(n[t],r))&&(r!==T||t in n)||st(n,t,r);
5657    }function ot(n,t,r){var e=n[t];ii.call(n,t)&&au(e,r)&&(r!==T||t in n)||st(n,t,r)}function ft(n,t){for(var r=n.length;r--;)if(au(n[r][0],t))return r;return-1}function ct(n,t,r,e){return eo(n,function(n,u,i){t(e,n,r(n),i)}),e}function at(n,t){return n&&Cr(t,zu(t),n)}function lt(n,t){return n&&Cr(t,Wu(t),n)}function st(n,t,r){"__proto__"==t&&mi?mi(n,t,{configurable:true,enumerable:true,value:r,writable:true}):n[t]=r}function ht(n,t){for(var r=-1,e=t.length,u=Vu(e),i=null==n;++r<e;)u[r]=i?T:Iu(n,t[r]);return u;
5658    }function pt(n,t,r){return n===n&&(r!==T&&(n=n<=r?n:r),t!==T&&(n=n>=t?n:t)),n}function _t(n,t,e,u,i,o){var f,c=1&t,a=2&t,l=4&t;if(e&&(f=i?e(n,u,i,o):e(n)),f!==T)return f;if(!gu(n))return n;if(u=of(n)){if(f=me(n),!c)return Ur(n,f)}else{var s=_o(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(cf(n))return Ir(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Ae(n),!c)return a?Mr(n,lt(f,n)):Dr(n,at(f,n))}else{if(!Ln[s])return i?n:{};f=ke(n,s,c)}}if(o||(o=new Pn),
5659            i=o.get(n))return i;
5659if(o.set(n,f),hf(n))return n.forEach(function(r){f.add(_t(r,t,e,r,n,o))}),f;if(lf(n))return n.forEach(function(r,u){f.set(u,_t(r,t,e,u,n,o))}),f;var a=l?a?ve:_e:a?Wu:zu,p=u?T:a(n);return r(p||n,function(r,u){p&&(u=r,r=n[u]),ot(f,u,_t(r,t,e,u,n,o))}),f}function vt(n){var t=zu(n);return function(r){return gt(r,n,t)}}function gt(n,t,r){var e=r.length;if(null==n)return!e;for(n=Yu(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===T&&!(u in n)||!i(o))return false}return true}function dt(n,t,r){if(typeof n!="function")throw new ni("Expected a function");
5660        return yo(function(){n.apply(T,r)},t)}function yt(n,t,r,e){var u=-1,i=o,a=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=c(t,E(r))),e?(i=f,a=false):200<=t.length&&(i=O,a=false,t=new Nn(t));n:for(;++u<l;){var p=n[u],_=null==r?p:r(p),p=e||0!==p?p:0;if(a&&_===_){for(var v=h;v--;)if(t[v]===_)continue n;s.push(p)}else i(t,_,e)||s.push(p)}return s}function bt(n,t){var r=true;return eo(n,function(n,e,u){return r=!!t(n,e,u)}),r}function xt(n,t,r){for(var e=-1,u=n.length;++e<u;){var i=n[e],o=t(i);if(null!=o&&(f===T?o===o&&!ju(o):r(o,f)))var f=o,c=i;
5661    }return c}function jt(n,t){var r=[];return eo(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function wt(n,t,r,e,u){var i=-1,o=n.length;for(r||(r=Ee),u||(u=[]);++i<o;){var f=n[i];0<t&&r(f)?1<t?wt(f,t-1,r,e,u):a(u,f):e||(u[u.length]=f)}return u}function mt(n,t){return n&&io(n,t,zu)}function At(n,t){return n&&oo(n,t,zu)}function kt(n,t){return i(t,function(t){return pu(n[t])})}function Et(n,t){t=Sr(t,n);for(var r=0,e=t.length;null!=n&&r<e;)n=n[De(t[r++])];return r&&r==e?n:T}function St(n,t,r){return t=t(n),
5662        of(n)?t:a(t,r(n))}function Ot(n){if(null==n)n=n===T?"[object Undefined]":"[object Null]";else if(wi&&wi in Yu(n)){var t=ii.call(n,wi),r=n[wi];try{n[wi]=T;var e=true}catch(n){}var u=ci.call(n);e&&(t?n[wi]=r:delete n[wi]),n=u}else n=ci.call(n);return n}function It(n,t){return n>t}function Rt(n,t){return null!=n&&ii.call(n,t)}function zt(n,t){return null!=n&&t in Yu(n)}function Wt(n,t,r){for(var e=r?f:o,u=n[0].length,i=n.length,a=i,l=Vu(i),s=1/0,h=[];a--;){var p=n[a];a&&t&&(p=c(p,E(t))),s=Ui(p.length,s),
5663        l[a]=!r&&(t||120<=u&&120<=p.length)?new Nn(a&&p):T}var p=n[0],_=-1,v=l[0];n:for(;++_<u&&h.length<s;){var g=p[_],d=t?t(g):g,g=r||0!==g?g:0;if(v?!O(v,d):!e(h,d,r)){for(a=i;--a;){var y=l[a];if(y?!O(y,d):!e(n[a],d,r))continue n}v&&v.push(d),h.push(g)}}return h}function Bt(n,t,r){var e={};return mt(n,function(n,u,i){t(e,r(n),u,i)}),e}function Lt(t,r,e){return r=Sr(r,t),t=2>r.length?t:Et(t,hr(r,0,-1)),r=null==t?t:t[De(qe(r))],null==r?T:n(r,t,e)}function Ut(n){return du(n)&&"[object Arguments]"==Ot(n)}function Ct(n){
5664        return du(n)&&"[object ArrayBuffer]"==Ot(n)}function Dt(n){return du(n)&&"[object Date]"==Ot(n)}function Mt(n,t,r,e,u){if(n===t)t=true;else if(null==n||null==t||!du(n)&&!du(t))t=n!==n&&t!==t;else n:{var i=of(n),o=of(t),f=i?"[object Array]":_o(n),c=o?"[object Array]":_o(t),f="[object Arguments]"==f?"[object Object]":f,c="[object Arguments]"==c?"[object Object]":c,a="[object Object]"==f,o="[object Object]"==c;if((c=f==c)&&cf(n)){if(!cf(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Pn),t=i||pf(n)?se(n,t,r,e,Mt,u):he(n,t,f,r,e,Mt,u);else{
5665        if(!(1&r)&&(i=a&&ii.call(n,"__wrapped__"),f=o&&ii.call(t,"__wrapped__"),i||f)){n=i?n.value():n,t=f?t.value():t,u||(u=new Pn),t=Mt(n,t,r,e,u);break n}if(c)t:if(u||(u=new Pn),i=1&r,f=_e(n),o=f.length,c=_e(t).length,o==c||i){for(a=o;a--;){var l=f[a];if(!(i?l in t:ii.call(t,l))){t=false;break t}}if((c=u.get(n))&&u.get(t))t=c==t;else{c=true,u.set(n,t),u.set(t,n);for(var s=i;++a<o;){var l=f[a],h=n[l],p=t[l];if(e)var _=i?e(p,h,l,t,n,u):e(h,p,l,n,t,u);if(_===T?h!==p&&!Mt(h,p,r,e,u):!_){c=false;break}s||(s="constructor"==l);
5666        }c&&!s&&(r=n.constructor,e=t.constructor,r!=e&&"constructor"in n&&"constructor"in t&&!(typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)&&(c=false)),u.delete(n),u.delete(t),t=c}}else t=false;else t=false}}return t}function Tt(n){return du(n)&&"[object Map]"==_o(n)}function $t(n,t,r,e){var u=r.length,i=u,o=!e;if(null==n)return!i;for(n=Yu(n);u--;){var f=r[u];
5666if(o&&f[2]?f[1]!==n[f[0]]:!(f[0]in n))return false}for(;++u<i;){var f=r[u],c=f[0],a=n[c],l=f[1];if(o&&f[2]){if(a===T&&!(c in n))return false;
5667    }else{if(f=new Pn,e)var s=e(a,l,c,n,t,f);if(s===T?!Mt(l,a,3,e,f):!s)return false}}return true}function Ft(n){return!(!gu(n)||fi&&fi in n)&&(pu(n)?si:dn).test(Me(n))}function Nt(n){return du(n)&&"[object RegExp]"==Ot(n)}function Pt(n){return du(n)&&"[object Set]"==_o(n)}function Zt(n){return du(n)&&vu(n.length)&&!!Bn[Ot(n)]}function qt(n){return typeof n=="function"?n:null==n?Tu:typeof n=="object"?of(n)?Jt(n[0],n[1]):Ht(n):Pu(n)}function Vt(n){if(!ze(n))return Bi(n);var t,r=[];for(t in Yu(n))ii.call(n,t)&&"constructor"!=t&&r.push(t);
5668        return r}function Kt(n,t){return n<t}function Gt(n,t){var r=-1,e=lu(n)?Vu(n.length):[];return eo(n,function(n,u,i){e[++r]=t(n,u,i)}),e}function Ht(n){var t=xe(n);return 1==t.length&&t[0][2]?We(t[0][0],t[0][1]):function(r){return r===n||$t(r,n,t)}}function Jt(n,t){return Ie(n)&&t===t&&!gu(t)?We(De(n),t):function(r){var e=Iu(r,n);return e===T&&e===t?Ru(r,n):Mt(t,e,3)}}function Yt(n,t,r,e,u){n!==t&&io(t,function(i,o){if(gu(i)){u||(u=new Pn);var f=u,c="__proto__"==o?T:n[o],a="__proto__"==o?T:t[o],l=f.get(a);
5669        if(l)it(n,o,l);else{var l=e?e(c,a,o+"",n,t,f):T,s=l===T;if(s){var h=of(a),p=!h&&cf(a),_=!h&&!p&&pf(a),l=a;h||p||_?of(c)?l=c:su(c)?l=Ur(c):p?(s=false,l=Ir(a,true)):_?(s=false,l=zr(a,true)):l=[]:bu(a)||uf(a)?(l=c,uf(c)?l=Su(c):(!gu(c)||r&&pu(c))&&(l=Ae(a))):s=false}s&&(f.set(a,l),Yt(l,a,r,e,f),f.delete(a)),it(n,o,l)}}else f=e?e("__proto__"==o?T:n[o],i,o+"",n,t,u):T,f===T&&(f=i),it(n,o,f)},Wu)}function Qt(n,t){var r=n.length;if(r)return t+=0>t?r:0,Se(t,r)?n[t]:T}function Xt(n,t,r){var e=-1;return t=c(t.length?t:[Tu],E(ye())),
5670        n=Gt(n,function(n){return{a:c(t,function(t){return t(n)}),b:++e,c:n}}),w(n,function(n,t){var e;n:{e=-1;for(var u=n.a,i=t.a,o=u.length,f=r.length;++e<o;){var c=Wr(u[e],i[e]);if(c){e=e>=f?c:c*("desc"==r[e]?-1:1);break n}}e=n.b-t.b}return e})}function nr(n,t){return tr(n,t,function(t,r){return Ru(n,r)})}function tr(n,t,r){for(var e=-1,u=t.length,i={};++e<u;){var o=t[e],f=Et(n,o);r(f,o)&&lr(i,Sr(o,n),f)}return i}function rr(n){return function(t){return Et(t,n)}}function er(n,t,r,e){var u=e?g:v,i=-1,o=t.length,f=n;
5671        for(n===t&&(t=Ur(t)),r&&(f=c(n,E(r)));++i<o;)for(var a=0,l=t[i],l=r?r(l):l;-1<(a=u(f,l,a,e));)f!==n&&bi.call(f,a,1),bi.call(n,a,1);return n}function ur(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];if(r==e||u!==i){var i=u;Se(u)?bi.call(n,u,1):xr(n,u)}}}function ir(n,t){return n+Oi(Mi()*(t-n+1))}function or(n,t){var r="";if(!n||1>t||9007199254740991<t)return r;do t%2&&(r+=n),(t=Oi(t/2))&&(n+=n);while(t);return r}function fr(n,t){return bo(Be(n,t,Tu),n+"")}function cr(n){return Qn(Lu(n))}function ar(n,t){
5672        var r=Lu(n);return Ce(r,pt(t,0,r.length))}function lr(n,t,r,e){if(!gu(n))return n;t=Sr(t,n);for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++u<i;){var c=De(t[u]),a=r;if(u!=o){var l=f[c],a=e?e(l,c,f):T;a===T&&(a=gu(l)?l:Se(t[u+1])?[]:{})}ot(f,c,a),f=f[c]}return n}function sr(n){return Ce(Lu(n))}function hr(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Vu(u);++e<u;)r[e]=n[e+t];return r}function pr(n,t){var r;return eo(n,function(n,e,u){return r=t(n,e,u),
5673        !r}),!!r}function _r(n,t,r){var e=0,u=null==n?e:n.length;if(typeof t=="number"&&t===t&&2147483647>=u){for(;e<u;){var i=e+u>>>1,o=n[i];null!==o&&!ju(o)&&(r?o<=t:o<t)?e=i+1:u=i}return u}return vr(n,t,Tu,r)}function vr(n,t,r,e){t=r(t);for(var u=0,i=null==n?0:n.length,o=t!==t,f=null===t,c=ju(t),a=t===T;u<i;){var l=Oi((u+i)/2),s=r(n[l]),h=s!==T,p=null===s,_=s===s,v=ju(s);(o?e||_:a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):p||v?0:e?s<=t:s<t)?u=l+1:i=l}return Ui(i,4294967294)}function gr(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){
5674        var o=n[r],f=t?t(o):o;if(!r||!au(f,c)){var c=f;i[u++]=0===o?0:o}}return i}function dr(n){return typeof n=="number"?n:ju(n)?F:+n}function yr(n){if(typeof n=="string")return n;if(of(n))return c(n,yr)+"";if(ju(n))return to?to.call(n):"";var t=n+"";return"0"==t&&1/n==-$?"-0":t}function br(n,t,r){var e=-1,u=o,i=n.length,c=true,a=[],l=a;if(r)c=false,u=f;else if(200<=i){if(u=t?null:lo(n))return U(u);c=false,u=O,l=new Nn}else l=t?[]:a;n:for(;++e<i;){var s=n[e],h=t?t(s):s,s=r||0!==s?s:0;if(c&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue n;
5675        t&&l.push(h),a.push(s)}else u(l,h,r)||(l!==a&&l.push(h),a.push(s))}return a}function xr(n,t){return t=Sr(t,n),n=2>t.length?n:Et(n,hr(t,0,-1)),null==n||delete n[De(qe(t))]}function jr(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?hr(n,e?0:i,e?i+1:u):hr(n,e?i+1:0,e?u:i)}function wr(n,t){var r=n;return r instanceof Un&&(r=r.value()),l(t,function(n,t){return t.func.apply(t.thisArg,a([n],t.args))},r)}function mr(n,t,r){var e=n.length;if(2>e)return e?br(n[0]):[];for(var u=-1,i=Vu(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=yt(i[u]||o,n[f],t,r));
5676        return br(wt(i,1),t,r)}function Ar(n,t,r){for(var e=-1,u=n.length,i=t.length,o={};++e<u;)r(o,n[e],e<i?t[e]:T);return o}function kr(n){return su(n)?n:[]}function Er(n){return typeof n=="function"?n:Tu}function Sr(n,t){return of(n)?n:Ie(n,t)?[n]:xo(Ou(n))}function Or(n,t,r){var e=n.length;return r=r===T?e:r,!t&&r>=e?n:hr(n,t,r)}function Ir(n,t){if(t)return n.slice();var r=n.length,r=vi?vi(r):new n.constructor(r);return n.copy(r),r}function Rr(n){var t=new n.constructor(n.byteLength);return new _i(t).set(new _i(n)),
5677        t}function zr(n,t){return new n.constructor(t?Rr(n.buffer):n.buffer,n.byteOffset,n.length)}function Wr(n,t){if(n!==t){var r=n!==T,e=null===n,u=n===n,i=ju(n),o=t!==T,f=null===t,c=t===t,a=ju(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&n<t||a&&r&&u&&!e&&!i||f&&r&&u||!o&&u||!c)return-1}return 0}function Br(n,t,r,e){var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Li(i-o,0),l=Vu(c+a);for(e=!e;++f<c;)l[f]=t[f];for(;++u<o;)(e||u<i)&&(l[r[u]]=n[u]);for(;a--;)l[f++]=n[u++];
5678        return l}function Lr(n,t,r,e){var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Li(i-f,0),s=Vu(l+a);for(e=!e;++u<l;)s[u]=n[u];for(l=u;++c<a;)s[l+c]=t[c];for(;++o<f;)(e||u<i)&&(s[l+r[o]]=n[u++]);return s}function Ur(n,t){var r=-1,e=n.length;for(t||(t=Vu(e));++r<e;)t[r]=n[r];return t}function Cr(n,t,r,e){var u=!r;r||(r={});for(var i=-1,o=t.length;++i<o;){var f=t[i],c=e?e(r[f],n[f],f,r,n):T;c===T&&(c=n[f]),u?st(r,f,c):ot(r,f,c)}return r}function Dr(n,t){return Cr(n,ho(n),t)}function Mr(n,t){return Cr(n,po(n),t);
5679    }function Tr(n,r){return function(e,u){var i=of(e)?t:ct,o=r?r():{};return i(e,n,ye(u,2),o)}}function $r(n){return fr(function(t,r){var e=-1,u=r.length,i=1<u?r[u-1]:T,o=2<u?r[2]:T,i=3<n.length&&typeof i=="function"?(u--,i):T;for(o&&Oe(r[0],r[1],o)&&(i=3>u?T:i,u=1),t=Yu(t);++e<u;)(o=r[e])&&n(t,o,e,i);return t})}function Fr(n,t){return function(r,e){if(null==r)return r;if(!lu(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=Yu(r);(t?i--:++i<u)&&false!==e(o[i],i,o););return r}}function Nr(n){return function(t,r,e){
5680        var u=-1,i=Yu(t);e=e(t);for(var o=e.length;o--;){var f=e[n?o:++u];if(false===r(i[f],f,i))break}return t}}function Pr(n,t,r){function e(){return(this&&this!==Fn&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=1&t,i=Vr(n);return e}function Zr(n){return function(t){t=Ou(t);var r=Rn.test(t)?M(t):T,e=r?r[0]:t.charAt(0);return t=r?Or(r,1).join(""):t.slice(1),e[n]()+t}}function qr(n){return function(t){return l(Du(Cu(t).replace(En,"")),n,"")}}function Vr(n){return function(){var t=arguments;switch(t.length){
5681        case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=ro(n.prototype),t=n.apply(r,t);return gu(t)?t:r}}function Kr(t,r,e){function u(){for(var o=arguments.length,f=Vu(o),c=o,a=de(u);c--;)f[c]=arguments[c];return c=3>o&&f[0]!==a&&f[o-1]!==a?[]:L(f,a),
5682        o-=c.length,o<e?ue(t,r,Jr,u.placeholder,T,f,c,T,T,e-o):n(this&&this!==Fn&&this instanceof u?i:t,this,f)}var i=Vr(t);return u}function Gr(n){return function(t,r,e){var u=Yu(t);if(!lu(t)){var i=ye(r,3);t=zu(t),r=function(n){return i(u[n],n,u)}}return r=n(t,r,e),-1<r?u[i?t[r]:r]:T}}function Hr(n){return pe(function(t){var r=t.length,e=r,u=On.prototype.thru;for(n&&t.reverse();e--;){var i=t[e];if(typeof i!="function")throw new ni("Expected a function");if(u&&!o&&"wrapper"==ge(i))var o=new On([],true)}for(e=o?e:r;
5682++e<r;)var i=t[e],u=ge(i),f="wrapper"==u?so(i):T,o=f&&Re(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?o[ge(f[0])].apply(o,f[3]):1==i.length&&Re(i)?o[u]():o.thru(i);
5683        return function(){var n=arguments,e=n[0];if(o&&1==n.length&&of(e))return o.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++u<r;)n=t[u].call(this,n);return n}})}function Jr(n,t,r,e,u,i,o,f,c,a){function l(){for(var d=arguments.length,y=Vu(d),b=d;b--;)y[b]=arguments[b];if(_){var x,j=de(l),b=y.length;for(x=0;b--;)y[b]===j&&++x}if(e&&(y=Br(y,e,u,_)),i&&(y=Lr(y,i,o,_)),d-=x,_&&d<a)return j=L(y,j),ue(n,t,Jr,l.placeholder,r,y,j,f,c,a-d);if(j=h?r:this,b=p?j[n]:n,d=y.length,f){x=y.length;for(var w=Ui(f.length,x),m=Ur(y);w--;){
5684        var A=f[w];y[w]=Se(A,x)?m[A]:T}}else v&&1<d&&y.reverse();return s&&c<d&&(y.length=c),this&&this!==Fn&&this instanceof l&&(b=g||Vr(b)),b.apply(j,y)}var s=128&t,h=1&t,p=2&t,_=24&t,v=512&t,g=p?T:Vr(n);return l}function Yr(n,t){return function(r,e){return Bt(r,n,t(e))}}function Qr(n,t){return function(r,e){var u;if(r===T&&e===T)return t;if(r!==T&&(u=r),e!==T){if(u===T)return e;typeof r=="string"||typeof e=="string"?(r=yr(r),e=yr(e)):(r=dr(r),e=dr(e)),u=n(r,e)}return u}}function Xr(t){return pe(function(r){
5685        return r=c(r,E(ye())),fr(function(e){var u=this;return t(r,function(t){return n(t,u,e)})})})}function ne(n,t){t=t===T?" ":yr(t);var r=t.length;return 2>r?r?or(t,n):t:(r=or(t,Si(n/D(t))),Rn.test(t)?Or(M(r),0,n).join(""):r.slice(0,n))}function te(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=Vu(l+c),h=this&&this!==Fn&&this instanceof i?f:t;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++r];return n(h,o?e:this,s)}var o=1&r,f=Vr(t);return i}function re(n){return function(t,r,e){
5686        e&&typeof e!="number"&&Oe(t,r,e)&&(r=e=T),t=mu(t),r===T?(r=t,t=0):r=mu(r),e=e===T?t<r?1:-1:mu(e);var u=-1;r=Li(Si((r-t)/(e||1)),0);for(var i=Vu(r);r--;)i[n?r:++u]=t,t+=e;return i}}function ee(n){return function(t,r){return typeof t=="string"&&typeof r=="string"||(t=Eu(t),r=Eu(r)),n(t,r)}}function ue(n,t,r,e,u,i,o,f,c,a){var l=8&t,s=l?o:T;o=l?T:o;var h=l?i:T;return i=l?T:i,t=(t|(l?32:64))&~(l?64:32),4&t||(t&=-4),u=[n,t,u,h,s,i,o,f,c,a],r=r.apply(T,u),Re(n)&&go(r,u),r.placeholder=e,Le(r,n,t)}function ie(n){
5687        var t=Ju[n];return function(n,r){if(n=Eu(n),r=null==r?0:Ui(Au(r),292)){var e=(Ou(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(Ou(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function oe(n){return function(t){var r=_o(t);return"[object Map]"==r?W(t):"[object Set]"==r?C(t):k(t,n(t))}}function fe(n,t,r,e,u,i,o,f){var c=2&t;if(!c&&typeof n!="function")throw new ni("Expected a function");var a=e?e.length:0;if(a||(t&=-97,e=u=T),o=o===T?o:Li(Au(o),0),f=f===T?f:Au(f),a-=u?u.length:0,64&t){
5688        var l=e,s=u;e=u=T}var h=c?T:so(n);return i=[n,t,r,e,u,l,s,i,o,f],h&&(r=i[1],n=h[1],t=r|n,e=128==n&&8==r||128==n&&256==r&&i[7].length<=h[8]||384==n&&h[7].length<=h[8]&&8==r,131>t||e)&&(1&n&&(i[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=i[3],i[3]=e?Br(e,r,h[4]):r,i[4]=e?L(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Lr(e,r,h[6]):r,i[6]=e?L(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Ui(i[8],h[8])),null==i[9]&&(i[9]=h[9]),i[0]=h[0],i[1]=t),n=i[0],t=i[1],
5689        r=i[2],e=i[3],u=i[4],f=i[9]=i[9]===T?c?0:n.length:Li(i[9]-a,0),!f&&24&t&&(t&=-25),Le((h?fo:go)(t&&1!=t?8==t||16==t?Kr(n,t,f):32!=t&&33!=t||u.length?Jr.apply(T,i):te(n,t,r,e):Pr(n,t,r),i),n,t)}function ce(n,t,r,e){return n===T||au(n,ri[r])&&!ii.call(e,r)?t:n}function ae(n,t,r,e,u,i){return gu(n)&&gu(t)&&(i.set(t,n),Yt(n,t,T,ae,i),i.delete(t)),n}function le(n){return bu(n)?T:n}function se(n,t,r,e,u,i){var o=1&r,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return false;if((c=i.get(n))&&i.get(t))return c==t;var c=-1,a=true,l=2&r?new Nn:T;
5690        for(i.set(n,t),i.set(t,n);++c<f;){var s=n[c],p=t[c];if(e)var _=o?e(p,s,c,t,n,i):e(s,p,c,n,t,i);if(_!==T){if(_)continue;a=false;break}if(l){if(!h(t,function(n,t){if(!O(l,t)&&(s===n||u(s,n,r,e,i)))return l.push(t)})){a=false;break}}else if(s!==p&&!u(s,p,r,e,i)){a=false;break}}return i.delete(n),i.delete(t),a}
5690function he(n,t,r,e,u,i,o){switch(r){case"[object DataView]":if(n.byteLength!=t.byteLength||n.byteOffset!=t.byteOffset)break;n=n.buffer,t=t.buffer;case"[object ArrayBuffer]":if(n.byteLength!=t.byteLength||!i(new _i(n),new _i(t)))break;
5691        return true;case"[object Boolean]":case"[object Date]":case"[object Number]":return au(+n,+t);case"[object Error]":return n.name==t.name&&n.message==t.message;case"[object RegExp]":case"[object String]":return n==t+"";case"[object Map]":var f=W;case"[object Set]":if(f||(f=U),n.size!=t.size&&!(1&e))break;return(r=o.get(n))?r==t:(e|=2,o.set(n,t),t=se(f(n),f(t),e,u,i,o),o.delete(n),t);case"[object Symbol]":if(no)return no.call(n)==no.call(t)}return false}function pe(n){return bo(Be(n,T,Pe),n+"")}function _e(n){
5692        return St(n,zu,ho)}function ve(n){return St(n,Wu,po)}function ge(n){for(var t=n.name+"",r=Ki[t],e=ii.call(Ki,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function de(n){return(ii.call(An,"placeholder")?An:n).placeholder}function ye(){var n=An.iteratee||$u,n=n===$u?qt:n;return arguments.length?n(arguments[0],arguments[1]):n}function be(n,t){var r=n.__data__,e=typeof t;return("string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t)?r[typeof t=="string"?"string":"hash"]:r.map;
5693    }function xe(n){for(var t=zu(n),r=t.length;r--;){var e=t[r],u=n[e];t[r]=[e,u,u===u&&!gu(u)]}return t}function je(n,t){var r=null==n?T:n[t];return Ft(r)?r:T}function we(n,t,r){t=Sr(t,n);for(var e=-1,u=t.length,i=false;++e<u;){var o=De(t[e]);if(!(i=null!=n&&r(n,o)))break;n=n[o]}return i||++e!=u?i:(u=null==n?0:n.length,!!u&&vu(u)&&Se(o,u)&&(of(n)||uf(n)))}function me(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&ii.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Ae(n){
5694        return typeof n.constructor!="function"||ze(n)?{}:ro(gi(n))}function ke(n,t,r){var e=n.constructor;switch(t){case"[object ArrayBuffer]":return Rr(n);case"[object Boolean]":case"[object Date]":return new e(+n);case"[object DataView]":return t=r?Rr(n.buffer):n.buffer,new n.constructor(t,n.byteOffset,n.byteLength);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":
5695        case"[object Uint16Array]":case"[object Uint32Array]":return zr(n,r);case"[object Map]":return new e;case"[object Number]":case"[object String]":return new e(n);case"[object RegExp]":return t=new n.constructor(n.source,_n.exec(n)),t.lastIndex=n.lastIndex,t;case"[object Set]":return new e;case"[object Symbol]":return no?Yu(no.call(n)):{}}}function Ee(n){return of(n)||uf(n)||!!(xi&&n&&n[xi])}function Se(n,t){var r=typeof n;return t=null==t?9007199254740991:t,!!t&&("number"==r||"symbol"!=r&&bn.test(n))&&-1<n&&0==n%1&&n<t;
5696    }function Oe(n,t,r){if(!gu(r))return false;var e=typeof t;return!!("number"==e?lu(r)&&Se(t,r.length):"string"==e&&t in r)&&au(r[t],n)}function Ie(n,t){if(of(n))return false;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!ju(n))||(nn.test(n)||!X.test(n)||null!=t&&n in Yu(t))}function Re(n){var t=ge(n),r=An[t];return typeof r=="function"&&t in Un.prototype&&(n===r||(t=so(r),!!t&&n===t[0]))}function ze(n){var t=n&&n.constructor;return n===(typeof t=="function"&&t.prototype||ri)}function We(n,t){
5697        return function(r){return null!=r&&(r[n]===t&&(t!==T||n in Yu(r)))}}function Be(t,r,e){return r=Li(r===T?t.length-1:r,0),function(){for(var u=arguments,i=-1,o=Li(u.length-r,0),f=Vu(o);++i<o;)f[i]=u[r+i];for(i=-1,o=Vu(r+1);++i<r;)o[i]=u[i];return o[r]=e(f),n(t,this,o)}}function Le(n,t,r){var e=t+"";t=bo;var u,i=Te;return u=(u=e.match(an))?u[1].split(ln):[],r=i(u,r),(i=r.length)&&(u=i-1,r[u]=(1<i?"& ":"")+r[u],r=r.join(2<i?", ":" "),e=e.replace(cn,"{\n/* [wrapped with "+r+"] */\n")),t(n,e)}function Ue(n){
5698        var t=0,r=0;return function(){var e=Ci(),u=16-(e-r);if(r=e,0<u){if(800<=++t)return arguments[0]}else t=0;return n.apply(T,arguments)}}function Ce(n,t){var r=-1,e=n.length,u=e-1;for(t=t===T?e:t;++r<t;){var e=ir(r,u),i=n[e];n[e]=n[r],n[r]=i}return n.length=t,n}function De(n){if(typeof n=="string"||ju(n))return n;var t=n+"";return"0"==t&&1/n==-$?"-0":t}function Me(n){if(null!=n){try{return ui.call(n)}catch(n){}return n+""}return""}function Te(n,t){return r(N,function(r){var e="_."+r[0];t&r[1]&&!o(n,e)&&n.push(e);
5699    }),n.sort()}function $e(n){if(n instanceof Un)return n.clone();var t=new On(n.__wrapped__,n.__chain__);return t.__actions__=Ur(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function Fe(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Au(r),0>r&&(r=Li(e+r,0)),_(n,ye(t,3),r)):-1}function Ne(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==T&&(u=Au(r),u=0>r?Li(e+u,0):Ui(u,e-1)),_(n,ye(t,3),u,true)}function Pe(n){return(null==n?0:n.length)?wt(n,1):[]}function Ze(n){
5700        return n&&n.length?n[0]:T}function qe(n){var t=null==n?0:n.length;return t?n[t-1]:T}function Ve(n,t){return n&&n.length&&t&&t.length?er(n,t):n}function Ke(n){return null==n?n:Ti.call(n)}function Ge(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){if(su(n))return t=Li(n.length,t),true}),A(t,function(t){return c(n,b(t))})}function He(t,r){if(!t||!t.length)return[];var e=Ge(t);return null==r?e:c(e,function(t){return n(r,T,t)})}
5700function Je(n){return n=An(n),n.__chain__=true,n}function Ye(n,t){
5701        return t(n)}function Qe(){return this}function Xe(n,t){return(of(n)?r:eo)(n,ye(t,3))}function nu(n,t){return(of(n)?e:uo)(n,ye(t,3))}function tu(n,t){return(of(n)?c:Gt)(n,ye(t,3))}function ru(n,t,r){return t=r?T:t,t=n&&null==t?n.length:t,fe(n,128,T,T,T,T,t)}function eu(n,t){var r;if(typeof t!="function")throw new ni("Expected a function");return n=Au(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=T),r}}function uu(n,t,r){return t=r?T:t,n=fe(n,8,T,T,T,T,T,t),n.placeholder=uu.placeholder,
5702        n}function iu(n,t,r){return t=r?T:t,n=fe(n,16,T,T,T,T,T,t),n.placeholder=iu.placeholder,n}function ou(n,t,r){function e(t){var r=c,e=a;return c=a=T,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===T||r>=t||0>r||g&&n>=l}function i(){var n=Ko();if(u(n))return o(n);var r,e=yo;r=n-_,n=t-(n-p),r=g?Ui(n,l-r):n,h=e(i,r)}function o(n){return h=T,d&&c?e(n):(c=a=T,s)}function f(){var n=Ko(),r=u(n);if(c=arguments,a=this,p=n,r){if(h===T)return _=n=p,h=yo(i,t),v?e(n):s;if(g)return h=yo(i,t),e(p)}return h===T&&(h=yo(i,t)),
5703        s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ni("Expected a function");return t=Eu(t)||0,gu(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Li(Eu(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==T&&ao(h),_=0,c=p=a=h=T},f.flush=function(){return h===T?s:o(Ko())},f}function fu(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;return i.has(u)?i.get(u):(e=n.apply(this,e),r.cache=i.set(u,e)||i,e)}if(typeof n!="function"||null!=t&&typeof t!="function")throw new ni("Expected a function");
5704        return r.cache=new(fu.Cache||$n),r}function cu(n){if(typeof n!="function")throw new ni("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function au(n,t){return n===t||n!==n&&t!==t}function lu(n){return null!=n&&vu(n.length)&&!pu(n)}function su(n){return du(n)&&lu(n)}function hu(n){if(!du(n))return false;var t=Ot(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!bu(n);
5705    }function pu(n){return!!gu(n)&&(n=Ot(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function _u(n){return typeof n=="number"&&n==Au(n)}function vu(n){return typeof n=="number"&&-1<n&&0==n%1&&9007199254740991>=n}function gu(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function du(n){return null!=n&&typeof n=="object"}function yu(n){return typeof n=="number"||du(n)&&"[object Number]"==Ot(n)}function bu(n){return!(!du(n)||"[object Object]"!=Ot(n))&&(n=gi(n),
5706        null===n||(n=ii.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&ui.call(n)==ai))}function xu(n){return typeof n=="string"||!of(n)&&du(n)&&"[object String]"==Ot(n)}function ju(n){return typeof n=="symbol"||du(n)&&"[object Symbol]"==Ot(n)}function wu(n){if(!n)return[];if(lu(n))return xu(n)?M(n):Ur(n);if(ji&&n[ji]){n=n[ji]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}return t=_o(n),("[object Map]"==t?W:"[object Set]"==t?U:Lu)(n)}function mu(n){return n?(n=Eu(n),
5707        n===$||n===-$?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function Au(n){n=mu(n);var t=n%1;return n===n?t?n-t:n:0}function ku(n){return n?pt(Au(n),0,4294967295):0}function Eu(n){if(typeof n=="number")return n;if(ju(n))return F;if(gu(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,n=gu(n)?n+"":n),typeof n!="string")return 0===n?n:+n;n=n.replace(un,"");var t=gn.test(n);return t||yn.test(n)?Mn(n.slice(2),t?2:8):vn.test(n)?F:+n}function Su(n){return Cr(n,Wu(n))}function Ou(n){return null==n?"":yr(n);
5708    }function Iu(n,t,r){return n=null==n?T:Et(n,t),n===T?r:n}function Ru(n,t){return null!=n&&we(n,t,zt)}function zu(n){return lu(n)?qn(n):Vt(n)}function Wu(n){if(lu(n))n=qn(n,true);else if(gu(n)){var t,r=ze(n),e=[];for(t in n)("constructor"!=t||!r&&ii.call(n,t))&&e.push(t);n=e}else{if(t=[],null!=n)for(r in Yu(n))t.push(r);n=t}return n}function Bu(n,t){if(null==n)return{};var r=c(ve(n),function(n){return[n]});return t=ye(t),tr(n,r,function(n,r){return t(n,r[0])})}function Lu(n){return null==n?[]:S(n,zu(n));
5709    }function Uu(n){return Tf(Ou(n).toLowerCase())}function Cu(n){return(n=Ou(n))&&n.replace(xn,Xn).replace(Sn,"")}function Du(n,t,r){return n=Ou(n),t=r?T:t,t===T?zn.test(n)?n.match(In)||[]:n.match(sn)||[]:n.match(t)||[]}function Mu(n){return function(){return n}}function Tu(n){return n}function $u(n){return qt(typeof n=="function"?n:_t(n,1))}function Fu(n,t,e){var u=zu(t),i=kt(t,u);null!=e||gu(t)&&(i.length||!u.length)||(e=t,t=n,n=this,i=kt(t,zu(t)));var o=!(gu(e)&&"chain"in e&&!e.chain),f=pu(n);return r(i,function(r){
5710        var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Ur(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,a([this.value()],arguments))})}),n}function Nu(){}function Pu(n){return Ie(n)?b(De(n)):rr(n)}function Zu(){return[]}function qu(){return false}mn=null==mn?Fn:rt.defaults(Fn.Object(),mn,rt.pick(Fn,Wn));var Vu=mn.Array,Ku=mn.Date,Gu=mn.Error,Hu=mn.Function,Ju=mn.Math,Yu=mn.Object,Qu=mn.RegExp,Xu=mn.String,ni=mn.TypeError,ti=Vu.prototype,ri=Yu.prototype,ei=mn["__core-js_shared__"],ui=Hu.prototype.toString,ii=ri.hasOwnProperty,oi=0,fi=function(){
5711        var n=/[^.]+$/.exec(ei&&ei.keys&&ei.keys.IE_PROTO||"");
5711return n?"Symbol(src)_1."+n:""}(),ci=ri.toString,ai=ui.call(Yu),li=Fn._,si=Qu("^"+ui.call(ii).replace(rn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),hi=Zn?mn.Buffer:T,pi=mn.Symbol,_i=mn.Uint8Array,vi=hi?hi.f:T,gi=B(Yu.getPrototypeOf,Yu),di=Yu.create,yi=ri.propertyIsEnumerable,bi=ti.splice,xi=pi?pi.isConcatSpreadable:T,ji=pi?pi.iterator:T,wi=pi?pi.toStringTag:T,mi=function(){try{var n=je(Yu,"defineProperty");
5712        return n({},"",{}),n}catch(n){}}(),Ai=mn.clearTimeout!==Fn.clearTimeout&&mn.clearTimeout,ki=Ku&&Ku.now!==Fn.Date.now&&Ku.now,Ei=mn.setTimeout!==Fn.setTimeout&&mn.setTimeout,Si=Ju.ceil,Oi=Ju.floor,Ii=Yu.getOwnPropertySymbols,Ri=hi?hi.isBuffer:T,zi=mn.isFinite,Wi=ti.join,Bi=B(Yu.keys,Yu),Li=Ju.max,Ui=Ju.min,Ci=Ku.now,Di=mn.parseInt,Mi=Ju.random,Ti=ti.reverse,$i=je(mn,"DataView"),Fi=je(mn,"Map"),Ni=je(mn,"Promise"),Pi=je(mn,"Set"),Zi=je(mn,"WeakMap"),qi=je(Yu,"create"),Vi=Zi&&new Zi,Ki={},Gi=Me($i),Hi=Me(Fi),Ji=Me(Ni),Yi=Me(Pi),Qi=Me(Zi),Xi=pi?pi.prototype:T,no=Xi?Xi.valueOf:T,to=Xi?Xi.toString:T,ro=function(){
5713        function n(){}return function(t){return gu(t)?di?di(t):(n.prototype=t,t=new n,n.prototype=T,t):{}}}();An.templateSettings={escape:J,evaluate:Y,interpolate:Q,variable:"",imports:{_:An}},An.prototype=kn.prototype,An.prototype.constructor=An,On.prototype=ro(kn.prototype),On.prototype.constructor=On,Un.prototype=ro(kn.prototype),Un.prototype.constructor=Un,Cn.prototype.clear=function(){this.__data__=qi?qi(null):{},this.size=0},Cn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n],
5714        this.size-=n?1:0,n},Cn.prototype.get=function(n){var t=this.__data__;return qi?(n=t[n],"__lodash_hash_undefined__"===n?T:n):ii.call(t,n)?t[n]:T},Cn.prototype.has=function(n){var t=this.__data__;return qi?t[n]!==T:ii.call(t,n)},Cn.prototype.set=function(n,t){var r=this.__data__;return this.size+=this.has(n)?0:1,r[n]=qi&&t===T?"__lodash_hash_undefined__":t,this},Tn.prototype.clear=function(){this.__data__=[],this.size=0},Tn.prototype.delete=function(n){var t=this.__data__;return n=ft(t,n),!(0>n)&&(n==t.length-1?t.pop():bi.call(t,n,1),
5715        --this.size,true)},Tn.prototype.get=function(n){var t=this.__data__;return n=ft(t,n),0>n?T:t[n][1]},Tn.prototype.has=function(n){return-1<ft(this.__data__,n)},Tn.prototype.set=function(n,t){var r=this.__data__,e=ft(r,n);return 0>e?(++this.size,r.push([n,t])):r[e][1]=t,this},$n.prototype.clear=function(){this.size=0,this.__data__={hash:new Cn,map:new(Fi||Tn),string:new Cn}},$n.prototype.delete=function(n){return n=be(this,n).delete(n),this.size-=n?1:0,n},$n.prototype.get=function(n){return be(this,n).get(n);
5716    },$n.prototype.has=function(n){return be(this,n).has(n)},$n.prototype.set=function(n,t){var r=be(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},Nn.prototype.add=Nn.prototype.push=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this},Nn.prototype.has=function(n){return this.__data__.has(n)},Pn.prototype.clear=function(){this.__data__=new Tn,this.size=0},Pn.prototype.delete=function(n){var t=this.__data__;return n=t.delete(n),this.size=t.size,n},Pn.prototype.get=function(n){
5717        return this.__data__.get(n)},Pn.prototype.has=function(n){return this.__data__.has(n)},Pn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Tn){var e=r.__data__;if(!Fi||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new $n(e)}return r.set(n,t),this.size=r.size,this};var eo=Fr(mt),uo=Fr(At,true),io=Nr(),oo=Nr(true),fo=Vi?function(n,t){return Vi.set(n,t),n}:Tu,co=mi?function(n,t){return mi(n,"toString",{configurable:true,enumerable:false,value:Mu(t),writable:true})}:Tu,ao=Ai||function(n){
5718            return Fn.clearTimeout(n)},lo=Pi&&1/U(new Pi([,-0]))[1]==$?function(n){return new Pi(n)}:Nu,so=Vi?function(n){return Vi.get(n)}:Nu,ho=Ii?function(n){return null==n?[]:(n=Yu(n),i(Ii(n),function(t){return yi.call(n,t)}))}:Zu,po=Ii?function(n){for(var t=[];n;)a(t,ho(n)),n=gi(n);return t}:Zu,_o=Ot;($i&&"[object DataView]"!=_o(new $i(new ArrayBuffer(1)))||Fi&&"[object Map]"!=_o(new Fi)||Ni&&"[object Promise]"!=_o(Ni.resolve())||Pi&&"[object Set]"!=_o(new Pi)||Zi&&"[object WeakMap]"!=_o(new Zi))&&(_o=function(n){
5719        var t=Ot(n);if(n=(n="[object Object]"==t?n.constructor:T)?Me(n):"")switch(n){case Gi:return"[object DataView]";case Hi:return"[object Map]";case Ji:return"[object Promise]";case Yi:return"[object Set]";case Qi:return"[object WeakMap]"}return t});var vo=ei?pu:qu,go=Ue(fo),yo=Ei||function(n,t){return Fn.setTimeout(n,t)},bo=Ue(co),xo=function(n){n=fu(n,function(n){return 500===t.size&&t.clear(),n});var t=n.cache;return n}(function(n){var t=[];return 46===n.charCodeAt(0)&&t.push(""),n.replace(tn,function(n,r,e,u){
5720        t.push(e?u.replace(hn,"$1"):r||n)}),t}),jo=fr(function(n,t){return su(n)?yt(n,wt(t,1,su,true)):[]}),wo=fr(function(n,t){var r=qe(t);return su(r)&&(r=T),su(n)?yt(n,wt(t,1,su,true),ye(r,2)):[]}),mo=fr(function(n,t){var r=qe(t);return su(r)&&(r=T),su(n)?yt(n,wt(t,1,su,true),T,r):[]}),Ao=fr(function(n){var t=c(n,kr);return t.length&&t[0]===n[0]?Wt(t):[]}),ko=fr(function(n){var t=qe(n),r=c(n,kr);return t===qe(r)?t=T:r.pop(),r.length&&r[0]===n[0]?Wt(r,ye(t,2)):[]}),Eo=fr(function(n){var t=qe(n),r=c(n,kr);return(t=typeof t=="function"?t:T)&&r.pop(),
5721        r.length&&r[0]===n[0]?Wt(r,T,t):[]}
5721),So=fr(Ve),Oo=pe(function(n,t){var r=null==n?0:n.length,e=ht(n,t);return ur(n,c(t,function(n){return Se(n,r)?+n:n}).sort(Wr)),e}),Io=fr(function(n){return br(wt(n,1,su,true))}),Ro=fr(function(n){var t=qe(n);return su(t)&&(t=T),br(wt(n,1,su,true),ye(t,2))}),zo=fr(function(n){var t=qe(n),t=typeof t=="function"?t:T;return br(wt(n,1,su,true),T,t)}),Wo=fr(function(n,t){return su(n)?yt(n,t):[]}),Bo=fr(function(n){return mr(i(n,su))}),Lo=fr(function(n){var t=qe(n);return su(t)&&(t=T),
5722        mr(i(n,su),ye(t,2))}),Uo=fr(function(n){var t=qe(n),t=typeof t=="function"?t:T;return mr(i(n,su),T,t)}),Co=fr(Ge),Do=fr(function(n){var t=n.length,t=1<t?n[t-1]:T,t=typeof t=="function"?(n.pop(),t):T;return He(n,t)}),Mo=pe(function(n){function t(t){return ht(t,n)}var r=n.length,e=r?n[0]:0,u=this.__wrapped__;return!(1<r||this.__actions__.length)&&u instanceof Un&&Se(e)?(u=u.slice(e,+e+(r?1:0)),u.__actions__.push({func:Ye,args:[t],thisArg:T}),new On(u,this.__chain__).thru(function(n){return r&&!n.length&&n.push(T),
5723        n})):this.thru(t)}),To=Tr(function(n,t,r){ii.call(n,r)?++n[r]:st(n,r,1)}),$o=Gr(Fe),Fo=Gr(Ne),No=Tr(function(n,t,r){ii.call(n,r)?n[r].push(t):st(n,r,[t])}),Po=fr(function(t,r,e){var u=-1,i=typeof r=="function",o=lu(t)?Vu(t.length):[];return eo(t,function(t){o[++u]=i?n(r,t,e):Lt(t,r,e)}),o}),Zo=Tr(function(n,t,r){st(n,r,t)}),qo=Tr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Vo=fr(function(n,t){if(null==n)return[];var r=t.length;return 1<r&&Oe(n,t[0],t[1])?t=[]:2<r&&Oe(t[0],t[1],t[2])&&(t=[t[0]]),
5724        Xt(n,wt(t,1),[])}),Ko=ki||function(){return Fn.Date.now()},Go=fr(function(n,t,r){var e=1;if(r.length)var u=L(r,de(Go)),e=32|e;return fe(n,e,t,r,u)}),Ho=fr(function(n,t,r){var e=3;if(r.length)var u=L(r,de(Ho)),e=32|e;return fe(t,e,n,r,u)}),Jo=fr(function(n,t){return dt(n,1,t)}),Yo=fr(function(n,t,r){return dt(n,Eu(t)||0,r)});fu.Cache=$n;var Qo=fr(function(t,r){r=1==r.length&&of(r[0])?c(r[0],E(ye())):c(wt(r,1),E(ye()));var e=r.length;return fr(function(u){for(var i=-1,o=Ui(u.length,e);++i<o;)u[i]=r[i].call(this,u[i]);
5725        return n(t,this,u)})}),Xo=fr(function(n,t){return fe(n,32,T,t,L(t,de(Xo)))}),nf=fr(function(n,t){return fe(n,64,T,t,L(t,de(nf)))}),tf=pe(function(n,t){return fe(n,256,T,T,T,t)}),rf=ee(It),ef=ee(function(n,t){return n>=t}),uf=Ut(function(){return arguments}())?Ut:function(n){return du(n)&&ii.call(n,"callee")&&!yi.call(n,"callee")},of=Vu.isArray,ff=Vn?E(Vn):Ct,cf=Ri||qu,af=Kn?E(Kn):Dt,lf=Gn?E(Gn):Tt,sf=Hn?E(Hn):Nt,hf=Jn?E(Jn):Pt,pf=Yn?E(Yn):Zt,_f=ee(Kt),vf=ee(function(n,t){return n<=t}),gf=$r(function(n,t){
5726        if(ze(t)||lu(t))Cr(t,zu(t),n);else for(var r in t)ii.call(t,r)&&ot(n,r,t[r])}),df=$r(function(n,t){Cr(t,Wu(t),n)}),yf=$r(function(n,t,r,e){Cr(t,Wu(t),n,e)}),bf=$r(function(n,t,r,e){Cr(t,zu(t),n,e)}),xf=pe(ht),jf=fr(function(n,t){n=Yu(n);var r=-1,e=t.length,u=2<e?t[2]:T;for(u&&Oe(t[0],t[1],u)&&(e=1);++r<e;)for(var u=t[r],i=Wu(u),o=-1,f=i.length;++o<f;){var c=i[o],a=n[c];(a===T||au(a,ri[c])&&!ii.call(n,c))&&(n[c]=u[c])}return n}),wf=fr(function(t){return t.push(T,ae),n(Sf,T,t)}),mf=Yr(function(n,t,r){
5727        null!=t&&typeof t.toString!="function"&&(t=ci.call(t)),n[t]=r},Mu(Tu)),Af=Yr(function(n,t,r){null!=t&&typeof t.toString!="function"&&(t=ci.call(t)),ii.call(n,t)?n[t].push(r):n[t]=[r]},ye),kf=fr(Lt),Ef=$r(function(n,t,r){Yt(n,t,r)}),Sf=$r(function(n,t,r,e){Yt(n,t,r,e)}),Of=pe(function(n,t){var r={};if(null==n)return r;var e=false;t=c(t,function(t){return t=Sr(t,n),e||(e=1<t.length),t}),Cr(n,ve(n),r),e&&(r=_t(r,7,le));for(var u=t.length;u--;)xr(r,t[u]);return r}),If=pe(function(n,t){return null==n?{}:nr(n,t);
5728    }),Rf=oe(zu),zf=oe(Wu),Wf=qr(function(n,t,r){return t=t.toLowerCase(),n+(r?Uu(t):t)}),Bf=qr(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Lf=qr(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),Uf=Zr("toLowerCase"),Cf=qr(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),Df=qr(function(n,t,r){return n+(r?" ":"")+Tf(t)}),Mf=qr(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),Tf=Zr("toUpperCase"),$f=fr(function(t,r){try{return n(t,T,r)}catch(n){return hu(n)?n:new Gu(n)}}),Ff=pe(function(n,t){
5729        return r(t,function(t){t=De(t),st(n,t,Go(n[t],n))}),n}),Nf=Hr(),Pf=Hr(true),Zf=fr(function(n,t){return function(r){return Lt(r,n,t)}}),qf=fr(function(n,t){return function(r){return Lt(n,r,t)}}),Vf=Xr(c),Kf=Xr(u),Gf=Xr(h),Hf=re(),Jf=re(true),Yf=Qr(function(n,t){return n+t},0),Qf=ie("ceil"),Xf=Qr(function(n,t){return n/t},1),nc=ie("floor"),tc=Qr(function(n,t){return n*t},1),rc=ie("round"),ec=Qr(function(n,t){return n-t},0);return An.after=function(n,t){if(typeof t!="function")throw new ni("Expected a function");
5730        return n=Au(n),function(){if(1>--n)return t.apply(this,arguments)}},An.ary=ru,An.assign=gf,An.assignIn=df,An.assignInWith=yf,An.assignWith=bf,An.at=xf,An.before=eu,An.bind=Go,An.bindAll=Ff,An.bindKey=Ho,An.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return of(n)?n:[n]},An.chain=Je,An.chunk=function(n,t,r){if(t=(r?Oe(n,t,r):t===T)?1:Li(Au(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Vu(Si(r/t));e<r;)i[u++]=hr(n,e,e+=t);return i},An.compact=function(n){for(var t=-1,r=null==n?0:n.length,e=0,u=[];++t<r;){
5731        var i=n[t];i&&(u[e++]=i)}return u},An.concat=function(){var n=arguments.length;if(!n)return[];for(var t=Vu(n-1),r=arguments[0];n--;)t[n-1]=arguments[n];return a(of(r)?Ur(r):[r],wt(t,1))},An.cond=function(t){var r=null==t?0:t.length,e=ye();return t=r?c(t,function(n){if("function"!=typeof n[1])throw new ni("Expected a function");return[e(n[0]),n[1]]}):[],fr(function(e){for(var u=-1;++u<r;){var i=t[u];
5731if(n(i[0],this,e))return n(i[1],this,e)}})},An.conforms=function(n){return vt(_t(n,1))},An.constant=Mu,
5732        An.countBy=To,An.create=function(n,t){var r=ro(n);return null==t?r:at(r,t)},An.curry=uu,An.curryRight=iu,An.debounce=ou,An.defaults=jf,An.defaultsDeep=wf,An.defer=Jo,An.delay=Yo,An.difference=jo,An.differenceBy=wo,An.differenceWith=mo,An.drop=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Au(t),hr(n,0>t?0:t,e)):[]},An.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Au(t),t=e-t,hr(n,0,0>t?0:t)):[]},An.dropRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true,true):[];
5733    },An.dropWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true):[]},An.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&Oe(n,t,r)&&(r=0,e=u),u=n.length,r=Au(r),0>r&&(r=-r>u?0:u+r),e=e===T||e>u?u:Au(e),0>e&&(e+=u),e=r>e?0:ku(e);r<e;)n[r++]=t;return n},An.filter=function(n,t){return(of(n)?i:jt)(n,ye(t,3))},An.flatMap=function(n,t){return wt(tu(n,t),1)},An.flatMapDeep=function(n,t){return wt(tu(n,t),$)},An.flatMapDepth=function(n,t,r){return r=r===T?1:Au(r),
5734        wt(tu(n,t),r)},An.flatten=Pe,An.flattenDeep=function(n){return(null==n?0:n.length)?wt(n,$):[]},An.flattenDepth=function(n,t){return null!=n&&n.length?(t=t===T?1:Au(t),wt(n,t)):[]},An.flip=function(n){return fe(n,512)},An.flow=Nf,An.flowRight=Pf,An.fromPairs=function(n){for(var t=-1,r=null==n?0:n.length,e={};++t<r;){var u=n[t];e[u[0]]=u[1]}return e},An.functions=function(n){return null==n?[]:kt(n,zu(n))},An.functionsIn=function(n){return null==n?[]:kt(n,Wu(n))},An.groupBy=No,An.initial=function(n){
5735        return(null==n?0:n.length)?hr(n,0,-1):[]},An.intersection=Ao,An.intersectionBy=ko,An.intersectionWith=Eo,An.invert=mf,An.invertBy=Af,An.invokeMap=Po,An.iteratee=$u,An.keyBy=Zo,An.keys=zu,An.keysIn=Wu,An.map=tu,An.mapKeys=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,t(n,e,u),n)}),r},An.mapValues=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,e,t(n,e,u))}),r},An.matches=function(n){return Ht(_t(n,1))},An.matchesProperty=function(n,t){return Jt(n,_t(t,1))},An.memoize=fu,
5736        An.merge=Ef,An.mergeWith=Sf,An.method=Zf,An.methodOf=qf,An.mixin=Fu,An.negate=cu,An.nthArg=function(n){return n=Au(n),fr(function(t){return Qt(t,n)})},An.omit=Of,An.omitBy=function(n,t){return Bu(n,cu(ye(t)))},An.once=function(n){return eu(2,n)},An.orderBy=function(n,t,r,e){return null==n?[]:(of(t)||(t=null==t?[]:[t]),r=e?T:r,of(r)||(r=null==r?[]:[r]),Xt(n,t,r))},An.over=Vf,An.overArgs=Qo,An.overEvery=Kf,An.overSome=Gf,An.partial=Xo,An.partialRight=nf,An.partition=qo,An.pick=If,An.pickBy=Bu,An.property=Pu,
5737        An.propertyOf=function(n){return function(t){return null==n?T:Et(n,t)}},An.pull=So,An.pullAll=Ve,An.pullAllBy=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,ye(r,2)):n},An.pullAllWith=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,T,r):n},An.pullAt=Oo,An.range=Hf,An.rangeRight=Jf,An.rearg=tf,An.reject=function(n,t){return(of(n)?i:jt)(n,cu(ye(t,3)))},An.remove=function(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=ye(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),
5738        u.push(e))}return ur(n,u),r},An.rest=function(n,t){if(typeof n!="function")throw new ni("Expected a function");return t=t===T?t:Au(t),fr(n,t)},An.reverse=Ke,An.sampleSize=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Au(t),(of(n)?et:ar)(n,t)},An.set=function(n,t,r){return null==n?n:lr(n,t,r)},An.setWith=function(n,t,r,e){return e=typeof e=="function"?e:T,null==n?n:lr(n,t,r,e)},An.shuffle=function(n){return(of(n)?ut:sr)(n)},An.slice=function(n,t,r){var e=null==n?0:n.length;return e?(r&&typeof r!="number"&&Oe(n,t,r)?(t=0,
5739        r=e):(t=null==t?0:Au(t),r=r===T?e:Au(r)),hr(n,t,r)):[]},An.sortBy=Vo,An.sortedUniq=function(n){return n&&n.length?gr(n):[]},An.sortedUniqBy=function(n,t){return n&&n.length?gr(n,ye(t,2)):[]},An.split=function(n,t,r){return r&&typeof r!="number"&&Oe(n,t,r)&&(t=r=T),r=r===T?4294967295:r>>>0,r?(n=Ou(n))&&(typeof t=="string"||null!=t&&!sf(t))&&(t=yr(t),!t&&Rn.test(n))?Or(M(n),0,r):n.split(t,r):[]},An.spread=function(t,r){if(typeof t!="function")throw new ni("Expected a function");return r=null==r?0:Li(Au(r),0),
5740        fr(function(e){var u=e[r];return e=Or(e,0,r),u&&a(e,u),n(t,this,e)})},An.tail=function(n){var t=null==n?0:n.length;return t?hr(n,1,t):[]},An.take=function(n,t,r){return n&&n.length?(t=r||t===T?1:Au(t),hr(n,0,0>t?0:t)):[]},An.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Au(t),t=e-t,hr(n,0>t?0:t,e)):[]},An.takeRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),false,true):[]},An.takeWhile=function(n,t){return n&&n.length?jr(n,ye(t,3)):[]},An.tap=function(n,t){return t(n),
5741        n},An.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ni("Expected a function");return gu(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),ou(n,t,{leading:e,maxWait:t,trailing:u})},An.thru=Ye,An.toArray=wu,An.toPairs=Rf,An.toPairsIn=zf,An.toPath=function(n){return of(n)?c(n,De):ju(n)?[n]:Ur(xo(Ou(n)))},An.toPlainObject=Su,An.transform=function(n,t,e){var u=of(n),i=u||cf(n)||pf(n);if(t=ye(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:gu(n)&&pu(o)?ro(gi(n)):{};
5742    }return(i?r:mt)(n,function(n,r,u){return t(e,n,r,u)}),e},An.unary=function(n){return ru(n,1)},An.union=Io,An.unionBy=Ro,An.unionWith=zo,An.uniq=function(n){return n&&n.length?br(n):[]},An.uniqBy=function(n,t){return n&&n.length?br(n,ye(t,2)):[]},An.uniqWith=function(n,t){return t=typeof t=="function"?t:T,n&&n.length?br(n,T,t):[]},An.unset=function(n,t){return null==n||xr(n,t)},An.unzip=Ge,An.unzipWith=He,An.update=function(n,t,r){return null==n?n:lr(n,t,Er(r)(Et(n,t)),void 0)},An.updateWith=function(n,t,r,e){
5743        return e=typeof e=="function"?e:T,null!=n&&(n=lr(n,t,Er(r)(Et(n,t)),e)),n},An.values=Lu,An.valuesIn=function(n){return null==n?[]:S(n,Wu(n))},An.without=Wo,An.words=Du,An.wrap=function(n,t){return Xo(Er(t),n)},An.xor=Bo,An.xorBy=Lo,An.xorWith=Uo,An.zip=Co,An.zipObject=function(n,t){return Ar(n||[],t||[],ot)},An.zipObjectDeep=function(n,t){return Ar(n||[],t||[],lr)},An.zipWith=Do,An.entries=Rf,An.entriesIn=zf,An.extend=df,An.extendWith=yf,Fu(An,An),An.add=Yf,An.attempt=$f,An.camel
5743Case=Wf,An.capitalize=Uu,
5744        An.ceil=Qf,An.clamp=function(n,t,r){return r===T&&(r=t,t=T),r!==T&&(r=Eu(r),r=r===r?r:0),t!==T&&(t=Eu(t),t=t===t?t:0),pt(Eu(n),t,r)},An.clone=function(n){return _t(n,4)},An.cloneDeep=function(n){return _t(n,5)},An.cloneDeepWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,5,t)},An.cloneWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,4,t)},An.conformsTo=function(n,t){return null==t||gt(n,t,zu(t))},An.deburr=Cu,An.defaultTo=function(n,t){return null==n||n!==n?t:n},An.divide=Xf,An.endsWith=function(n,t,r){
5745            n=Ou(n),t=yr(t);var e=n.length,e=r=r===T?e:pt(Au(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},An.eq=au,An.escape=function(n){return(n=Ou(n))&&H.test(n)?n.replace(K,nt):n},An.escapeRegExp=function(n){return(n=Ou(n))&&en.test(n)?n.replace(rn,"\\$&"):n},An.every=function(n,t,r){var e=of(n)?u:bt;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.find=$o,An.findIndex=Fe,An.findKey=function(n,t){return p(n,ye(t,3),mt)},An.findLast=Fo,An.findLastIndex=Ne,An.findLastKey=function(n,t){return p(n,ye(t,3),At);
5746        },An.floor=nc,An.forEach=Xe,An.forEachRight=nu,An.forIn=function(n,t){return null==n?n:io(n,ye(t,3),Wu)},An.forInRight=function(n,t){return null==n?n:oo(n,ye(t,3),Wu)},An.forOwn=function(n,t){return n&&mt(n,ye(t,3))},An.forOwnRight=function(n,t){return n&&At(n,ye(t,3))},An.get=Iu,An.gt=rf,An.gte=ef,An.has=function(n,t){return null!=n&&we(n,t,Rt)},An.hasIn=Ru,An.head=Ze,An.identity=Tu,An.includes=function(n,t,r,e){return n=lu(n)?n:Lu(n),r=r&&!e?Au(r):0,e=n.length,0>r&&(r=Li(e+r,0)),xu(n)?r<=e&&-1<n.indexOf(t,r):!!e&&-1<v(n,t,r);
5747        },An.indexOf=function(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Au(r),0>r&&(r=Li(e+r,0)),v(n,t,r)):-1},An.inRange=function(n,t,r){return t=mu(t),r===T?(r=t,t=0):r=mu(r),n=Eu(n),n>=Ui(t,r)&&n<Li(t,r)},An.invoke=kf,An.isArguments=uf,An.isArray=of,An.isArrayBuffer=ff,An.isArrayLike=lu,An.isArrayLikeObject=su,An.isBoolean=function(n){return true===n||false===n||du(n)&&"[object Boolean]"==Ot(n)},An.isBuffer=cf,An.isDate=af,An.isElement=function(n){return du(n)&&1===n.nodeType&&!bu(n)},An.isEmpty=function(n){
5748            if(null==n)return true;if(lu(n)&&(of(n)||typeof n=="string"||typeof n.splice=="function"||cf(n)||pf(n)||uf(n)))return!n.length;var t=_o(n);if("[object Map]"==t||"[object Set]"==t)return!n.size;if(ze(n))return!Vt(n).length;for(var r in n)if(ii.call(n,r))return false;return true},An.isEqual=function(n,t){return Mt(n,t)},An.isEqualWith=function(n,t,r){var e=(r=typeof r=="function"?r:T)?r(n,t):T;return e===T?Mt(n,t,T,r):!!e},An.isError=hu,An.isFinite=function(n){return typeof n=="number"&&zi(n)},An.isFunction=pu,
5749        An.isInteger=_u,An.isLength=vu,An.isMap=lf,An.isMatch=function(n,t){return n===t||$t(n,t,xe(t))},An.isMatchWith=function(n,t,r){return r=typeof r=="function"?r:T,$t(n,t,xe(t),r)},An.isNaN=function(n){return yu(n)&&n!=+n},An.isNative=function(n){if(vo(n))throw new Gu("Unsupported core-js use. Try https://npms.io/search?q=ponyfill.");return Ft(n)},An.isNil=function(n){return null==n},An.isNull=function(n){return null===n},An.isNumber=yu,An.isObject=gu,An.isObjectLike=du,An.isPlainObject=bu,An.isRegExp=sf,
5750        An.isSafeInteger=function(n){return _u(n)&&-9007199254740991<=n&&9007199254740991>=n},An.isSet=hf,An.isString=xu,An.isSymbol=ju,An.isTypedArray=pf,An.isUndefined=function(n){return n===T},An.isWeakMap=function(n){return du(n)&&"[object WeakMap]"==_o(n)},An.isWeakSet=function(n){return du(n)&&"[object WeakSet]"==Ot(n)},An.join=function(n,t){return null==n?"":Wi.call(n,t)},An.kebabCase=Bf,An.last=qe,An.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==T&&(u=Au(r),u=0>u?Li(e+u,0):Ui(u,e-1)),
5751            t===t){for(r=u+1;r--&&n[r]!==t;);n=r}else n=_(n,d,u,true);return n},An.lowerCase=Lf,An.lowerFirst=Uf,An.lt=_f,An.lte=vf,An.max=function(n){return n&&n.length?xt(n,Tu,It):T},An.maxBy=function(n,t){return n&&n.length?xt(n,ye(t,2),It):T},An.mean=function(n){return y(n,Tu)},An.meanBy=function(n,t){return y(n,ye(t,2))},An.min=function(n){return n&&n.length?xt(n,Tu,Kt):T},An.minBy=function(n,t){return n&&n.length?xt(n,ye(t,2),Kt):T},An.stubArray=Zu,An.stubFalse=qu,An.stubObject=function(){return{}},An.stubString=function(){
5752            return""},An.stubTrue=function(){return true},An.multiply=tc,An.nth=function(n,t){return n&&n.length?Qt(n,Au(t)):T},An.noConflict=function(){return Fn._===this&&(Fn._=li),this},An.noop=Nu,An.now=Ko,An.pad=function(n,t,r){n=Ou(n);var e=(t=Au(t))?D(n):0;return!t||e>=t?n:(t=(t-e)/2,ne(Oi(t),r)+n+ne(Si(t),r))},An.padEnd=function(n,t,r){n=Ou(n);var e=(t=Au(t))?D(n):0;return t&&e<t?n+ne(t-e,r):n},An.padStart=function(n,t,r){n=Ou(n);var e=(t=Au(t))?D(n):0;return t&&e<t?ne(t-e,r)+n:n},An.parseInt=function(n,t,r){
5753            return r||null==t?t=0:t&&(t=+t),Di(Ou(n).replace(on,""),t||0)},An.random=function(n,t,r){if(r&&typeof r!="boolean"&&Oe(n,t,r)&&(t=r=T),r===T&&(typeof t=="boolean"?(r=t,t=T):typeof n=="boolean"&&(r=n,n=T)),n===T&&t===T?(n=0,t=1):(n=mu(n),t===T?(t=n,n=0):t=mu(t)),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Mi(),Ui(n+r*(t-n+Dn("1e-"+((r+"").length-1))),t)):ir(n,t)},An.reduce=function(n,t,r){var e=of(n)?l:j,u=3>arguments.length;return e(n,ye(t,4),r,u,eo)},An.reduceRight=function(n,t,r){var e=of(n)?s:j,u=3>arguments.length;
5754            return e(n,ye(t,4),r,u,uo)},An.repeat=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Au(t),or(Ou(n),t)},An.replace=function(){var n=arguments,t=Ou(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},An.result=function(n,t,r){t=Sr(t,n);var e=-1,u=t.length;for(u||(u=1,n=T);++e<u;){var i=null==n?T:n[De(t[e])];i===T&&(e=u,i=r),n=pu(i)?i.call(n):i}return n},An.round=rc,An.runInContext=x,An.sample=function(n){return(of(n)?Qn:cr)(n)},An.size=function(n){if(null==n)return 0;if(lu(n))return xu(n)?D(n):n.length;
5755            var t=_o(n);return"[object Map]"==t||"[object Set]"==t?n.size:Vt(n).length},An.snakeCase=Cf,An.some=function(n,t,r){var e=of(n)?h:pr;
5755return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.sortedIndex=function(n,t){return _r(n,t)},An.sortedIndexBy=function(n,t,r){return vr(n,t,ye(r,2))},An.sortedIndexOf=function(n,t){var r=null==n?0:n.length;if(r){var e=_r(n,t);if(e<r&&au(n[e],t))return e}return-1},An.sortedLastIndex=function(n,t){return _r(n,t,true)},An.sortedLastIndexBy=function(n,t,r){return vr(n,t,ye(r,2),true);
5756        },An.sortedLastIndexOf=function(n,t){if(null==n?0:n.length){var r=_r(n,t,true)-1;if(au(n[r],t))return r}return-1},An.startCase=Df,An.startsWith=function(n,t,r){return n=Ou(n),r=null==r?0:pt(Au(r),0,n.length),t=yr(t),n.slice(r,r+t.length)==t},An.subtract=ec,An.sum=function(n){return n&&n.length?m(n,Tu):0},An.sumBy=function(n,t){return n&&n.length?m(n,ye(t,2)):0},An.template=function(n,t,r){var e=An.templateSettings;r&&Oe(n,t,r)&&(t=T),n=Ou(n),t=yf({},t,e,ce),r=yf({},t.imports,e.imports,ce);var u,i,o=zu(r),f=S(r,o),c=0;
5757            r=t.interpolate||jn;var a="__p+='";r=Qu((t.escape||jn).source+"|"+r.source+"|"+(r===Q?pn:jn).source+"|"+(t.evaluate||jn).source+"|$","g");var l="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,o,f,l){return e||(e=o),a+=n.slice(c,l).replace(wn,z),r&&(u=true,a+="'+__e("+r+")+'"),f&&(i=true,a+="';"+f+";\n__p+='"),e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+t.length,t}),a+="';",(t=t.variable)||(a="with(obj){"+a+"}"),a=(i?a.replace(P,""):a).replace(Z,"$1").replace(q,"$1;"),
5758                    a="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",t=$f(function(){return Hu(o,l+"return "+a).apply(T,f)}),t.source=a,hu(t))throw t;return t},An.times=function(n,t){if(n=Au(n),1>n||9007199254740991<n)return[];var r=4294967295,e=Ui(n,4294967295);for(t=ye(t),n-=4294967295,e=A(e,t);++r<n;)t(r);return e},An.toFinite=mu,An.toInteger=Au,An.toLength=ku,An.toLower=function(n){
5759            return Ou(n).toLowerCase()},An.toNumber=Eu,An.toSafeInteger=function(n){return n?pt(Au(n),-9007199254740991,9007199254740991):0===n?n:0},An.toString=Ou,An.toUpper=function(n){return Ou(n).toUpperCase()},An.trim=function(n,t,r){return(n=Ou(n))&&(r||t===T)?n.replace(un,""):n&&(t=yr(t))?(n=M(n),r=M(t),t=I(n,r),r=R(n,r)+1,Or(n,t,r).join("")):n},An.trimEnd=function(n,t,r){return(n=Ou(n))&&(r||t===T)?n.replace(fn,""):n&&(t=yr(t))?(n=M(n),t=R(n,M(t))+1,Or(n,0,t).join("")):n},An.trimStart=function(n,t,r){
5760            return(n=Ou(n))&&(r||t===T)?n.replace(on,""):n&&(t=yr(t))?(n=M(n),t=I(n,M(t)),Or(n,t).join("")):n},An.truncate=function(n,t){var r=30,e="...";if(gu(t))var u="separator"in t?t.separator:u,r="length"in t?Au(t.length):r,e="omission"in t?yr(t.omission):e;n=Ou(n);var i=n.length;if(Rn.test(n))var o=M(n),i=o.length;if(r>=i)return n;if(i=r-D(e),1>i)return e;if(r=o?Or(o,0,i).join(""):n.slice(0,i),u===T)return r+e;if(o&&(i+=r.length-i),sf(u)){if(n.slice(i).search(u)){var f=r;for(u.global||(u=Qu(u.source,Ou(_n.exec(u))+"g")),
5761                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===T?i:c)}}else n.indexOf(yr(u),i)!=i&&(u=r.lastIndexOf(u),-1<u&&(r=r.slice(0,u)));return r+e},An.unescape=function(n){return(n=Ou(n))&&G.test(n)?n.replace(V,tt):n},An.uniqueId=function(n){var t=++oi;return Ou(n)+t},An.upperCase=Mf,An.upperFirst=Tf,An.each=Xe,An.eachRight=nu,An.first=Ze,Fu(An,function(){var n={};return mt(An,function(t,r){ii.call(An.prototype,r)||(n[r]=t)}),n}(),{chain:false}),An.VERSION="4.17.5",r("bind bindKey curry curryRight partial partialRight".split(" "),function(n){
5762            An[n].placeholder=An}),r(["drop","take"],function(n,t){Un.prototype[n]=function(r){r=r===T?1:Li(Au(r),0);var e=this.__filtered__&&!t?new Un(this):this.clone();return e.__filtered__?e.__takeCount__=Ui(r,e.__takeCount__):e.__views__.push({size:Ui(r,4294967295),type:n+(0>e.__dir__?"Right":"")}),e},Un.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),r(["filter","map","takeWhile"],function(n,t){var r=t+1,e=1==r||3==r;Un.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({
5763            iteratee:ye(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),r(["head","last"],function(n,t){var r="take"+(t?"Right":"");
5763Un.prototype[n]=function(){return this[r](1).value()[0]}}),r(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Un.prototype[n]=function(){return this.__filtered__?new Un(this):this[r](1)}}),Un.prototype.compact=function(){return this.filter(Tu)},Un.prototype.find=function(n){return this.filter(n).head()},Un.prototype.findLast=function(n){return this.reverse().find(n);
5764        },Un.prototype.invokeMap=fr(function(n,t){return typeof n=="function"?new Un(this):this.map(function(r){return Lt(r,n,t)})}),Un.prototype.reject=function(n){return this.filter(cu(ye(n)))},Un.prototype.slice=function(n,t){n=Au(n);var r=this;return r.__filtered__&&(0<n||0>t)?new Un(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==T&&(t=Au(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Un.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},Un.prototype.toArray=function(){return this.take(4294967295);
5765        },mt(Un.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=An[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(An.prototype[t]=function(){function t(n){return n=u.apply(An,a([n],f)),e&&h?n[0]:n}var o=this.__wrapped__,f=e?[1]:arguments,c=o instanceof Un,l=f[0],s=c||of(o);s&&r&&typeof l=="function"&&1!=l.length&&(c=s=false);var h=this.__chain__,p=!!this.__actions__.length,l=i&&!h,c=c&&!p;return!i&&s?(o=c?o:new Un(this),o=n.apply(o,f),o.__actions__.push({
5766            func:Ye,args:[t],thisArg:T}),new On(o,h)):l&&c?n.apply(this,f):(o=this.thru(t),l?e?o.value()[0]:o.value():o)})}),r("pop push shift sort splice unshift".split(" "),function(n){var t=ti[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);An.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(of(u)?u:[],n)}return this[r](function(r){return t.apply(of(r)?r:[],n)})}}),mt(Un.prototype,function(n,t){var r=An[t];if(r){var e=r.name+"";
5767            (Ki[e]||(Ki[e]=[])).push({name:t,func:r})}}),Ki[Jr(T,2).name]=[{name:"wrapper",func:T}],Un.prototype.clone=function(){var n=new Un(this.__wrapped__);return n.__actions__=Ur(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Ur(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Ur(this.__views__),n},Un.prototype.reverse=function(){if(this.__filtered__){var n=new Un(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n;
5768        },Un.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=of(t),u=0>r,i=e?t.length:0;n=i;for(var o=this.__views__,f=0,c=-1,a=o.length;++c<a;){var l=o[c],s=l.size;switch(l.type){case"drop":f+=s;break;case"dropRight":n-=s;break;case"take":n=Ui(n,f+s);break;case"takeRight":f=Li(f,n-s)}}if(n={start:f,end:n},o=n.start,f=n.end,n=f-o,o=u?f:o-1,f=this.__iteratees__,c=f.length,a=0,l=Ui(n,this.__takeCount__),!e||!u&&i==n&&l==n)return wr(t,this.__actions__);e=[];n:for(;n--&&a<l;){for(o+=r,
5769                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  u=-1,i=t[o];++u<c;){var h=f[u],s=h.type,h=(0,h.iteratee)(i);if(2==s)i=h;else if(!h){if(1==s)continue n;break n}}e[a++]=i}return e},An.prototype.at=Mo,An.prototype.chain=function(){return Je(this)},An.prototype.commit=function(){return new On(this.value(),this.__chain__)},An.prototype.next=function(){this.__values__===T&&(this.__values__=wu(this.value()));var n=this.__index__>=this.__values__.length;return{done:n,value:n?T:this.__values__[this.__index__++]}},An.prototype.plant=function(n){for(var t,r=this;r instanceof kn;){
5770            var e=$e(r);e.__index__=0,e.__values__=T,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},An.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Un?(this.__actions__.length&&(n=new Un(this)),n=n.reverse(),n.__actions__.push({func:Ye,args:[Ke],thisArg:T}),new On(n,this.__chain__)):this.thru(Ke)},An.prototype.toJSON=An.prototype.valueOf=An.prototype.value=function(){return wr(this.__wrapped__,this.__actions__)},An.prototype.first=An.prototype.head,ji&&(An.prototype[ji]=Qe),
5771        An}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Fn._=rt, define(function(){return rt})):Pn?((Pn.exports=rt)._=rt,Nn._=rt):Fn._=rt}).call(this);
5772
5773/*! Hammer.JS - v2.0.8 - 2016-04-23
5774 * http://hammerjs.github.io/
5775 *
5776 * Copyright (c) 2016 Jorik Tangelder;
5777 * Licensed under the MIT license */
5778(function(window, document, exportName, undefined) {
5779	'use strict';
5780
5781	var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
5782	var TEST_ELEMENT = document.createElement('div');
5783
5784	var TYPE_FUNCTION = 'function';
5785
5786	var round = Math.round;
5787	var abs = Math.abs;
5788	var now = Date.now;
5789
5790	/**
5791	 * set a timeout with a given scope
5792	 * @param {Function} fn
5793	 * @param {Number} timeout
5794	 * @param {Object} context
5795	 * @returns {number}
5796	 */
5797	function setTimeoutContext(fn, timeout, context) {
5798		return setTimeout(bindFn(fn, context), timeout);
5799	}
5800
5801	/**
5802	 * if the argument is an array, we want to execute the fn on each entry
5803	 * if it aint an array we don't want to do a thing.
5804	 * this is used by all the methods that accept a single and array argument.
5805	 * @param {*|Array} arg
5806	 * @param {String} fn
5807	 * @param {Object} [context]
5808	 * @returns {Boolean}
5809	 */
5810	function invokeArrayArg(arg, fn, context) {
5811		if (Array.isArray(arg)) {
5812			each(arg, context[fn], context);
5813			return true;
5814		}
5815		return false;
vendor: 60,871 bytes, lines 5816-8173
5816	}
5817
5818	/**
5819	 * walk objects and arrays
5820	 * @param {Object} obj
5821	 * @param {Function} iterator
5822	 * @param {Object} context
5823	 */
5824	function each(obj, iterator, context) {
5825		var i;
5826
5827		if (!obj) {
5828			return;
5829		}
5830
5831		if (obj.forEach) {
5832			obj.forEach(iterator, context);
5833		} else if (obj.length !== undefined) {
5834			i = 0;
5835			while (i < obj.length) {
5836				iterator.call(context, obj[i], i, obj);
5837				i++;
5838			}
5839		} else {
5840			for (i in obj) {
5841				obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
5842			}
5843		}
5844	}
5845
5846	/**
5847	 * wrap a method with a deprecation warning and stack trace
5848	 * @param {Function} method
5849	 * @param {String} name
5850	 * @param {String} message
5851	 * @returns {Function} A new function wrapping the supplied method.
5852	 */
5853	function deprecate(method, name, message) {
5854		var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\n' + message + ' AT \n';
5855		return function() {
5856			var e = new Error('get-stack-trace');
5857			var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '')
5858				.replace(/^\s+at\s+/gm, '')
5859				.replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';
5860
5861			var log = window.console && (window.console.warn || window.console.log);
5862			if (log) {
5863				log.call(window.console, deprecationMessage, stack);
5864			}
5865			return method.apply(this, arguments);
5866		};
5867	}
5868
5869	/**
5870	 * extend object.
5871	 * means that properties in dest will be overwritten by the ones in src.
5872	 * @param {Object} target
5873	 * @param {...Object} objects_to_assign
5874	 * @returns {Object} target
5875	 */
5876	var assign;
5877	if (typeof Object.assign !== 'function') {
5878		assign = function assign(target) {
5879			if (target === undefined || target === null) {
5880				throw new TypeError('Cannot convert undefined or null to object');
5881			}
5882
5883			var output = Object(target);
5884			for (var index = 1; index < arguments.length; index++) {
5885				var source = arguments[index];
5886				if (source !== undefined && source !== null) {
5887					for (var nextKey in source) {
5888						if (source.hasOwnProperty(nextKey)) {
5889							output[nextKey] = source[nextKey];
5890						}
5891					}
5892				}
5893			}
5894			return output;
5895		};
5896	} else {
5897		assign = Object.assign;
5898	}
5899
5900	/**
5901	 * extend object.
5902	 * means that properties in dest will be overwritten by the ones in src.
5903	 * @param {Object} dest
5904	 * @param {Object} src
5905	 * @param {Boolean} [merge=false]
5906	 * @returns {Object} dest
5907	 */
5908	var extend = deprecate(function extend(dest, src, merge) {
5909		var keys = Object.keys(src);
5910		var i = 0;
5911		while (i < keys.length) {
5912			if (!merge || (merge && dest[keys[i]] === undefined)) {
5913				dest[keys[i]] = src[keys[i]];
5914			}
5915			i++;
5916		}
5917		return dest;
5918	}, 'extend', 'Use `assign`.');
5919
5920	/**
5921	 * merge the values from src in the dest.
5922	 * means that properties that exist in dest will not be overwritten by src
5923	 * @param {Object} dest
5924	 * @param {Object} src
5925	 * @returns {Object} dest
5926	 */
5927	var merge = deprecate(function merge(dest, src) {
5928		return extend(dest, src, true);
5929	}, 'merge', 'Use `assign`.');
5930
5931	/**
5932	 * simple class inheritance
5933	 * @param {Function} child
5934	 * @param {Function} base
5935	 * @param {Object} [properties]
5936	 */
5937	function inherit(child, base, properties) {
5938		var baseP = base.prototype,
5939			childP;
5940
5941		childP = child.prototype = Object.create(baseP);
5942		childP.constructor = child;
5943		childP._super = baseP;
5944
5945		if (properties) {
5946			assign(childP, properties);
5947		}
5948	}
5949
5950	/**
5951	 * simple function bind
5952	 * @param {Function} fn
5953	 * @param {Object} context
5954	 * @returns {Function}
5955	 */
5956	function bindFn(fn, context) {
5957		return function boundFn() {
5958			return fn.apply(context, arguments);
5959		};
5960	}
5961
5962	/**
5963	 * let a boolean value also be a function that must return a boolean
5964	 * this first item in args will be used as the context
5965	 * @param {Boolean|Function} val
5966	 * @param {Array} [args]
5967	 * @returns {Boolean}
5968	 */
5969	function boolOrFn(val, args) {
5970		if (typeof val == TYPE_FUNCTION) {
5971			return val.apply(args ? args[0] || undefined : undefined, args);
5972		}
5973		return val;
5974	}
5975
5976	/**
5977	 * use the val2 when val1 is undefined
5978	 * @param {*} val1
5979	 * @param {*} val2
5980	 * @returns {*}
5981	 */
5982	function ifUndefined(val1, val2) {
5983		return (val1 === undefined) ? val2 : val1;
5984	}
5985
5986	/**
5987	 * addEventListener with multiple events at once
5988	 * @param {EventTarget} target
5989	 * @param {String} types
5990	 * @param {Function} handler
5991	 */
5992	function addEventListeners(target, types, handler) {
5993		each(splitStr(types), function(type) {
5994			target.addEventListener(type, handler, false);
5995		});
5996	}
5997
5998	/**
5999	 * removeEventListener with multiple events at once
6000	 * @param {EventTarget} target
6001	 * @param {String} types
6002	 * @param {Function} handler
6003	 */
6004	function removeEventListeners(target, types, handler) {
6005		each(splitStr(types), function(type) {
6006			target.removeEventListener(type, handler, false);
6007		});
6008	}
6009
6010	/**
6011	 * find if a node is in the given parent
6012	 * @method hasParent
6013	 * @param {HTMLElement} node
6014	 * @param {HTMLElement} parent
6015	 * @return {Boolean} found
6016	 */
6017	function hasParent(node, parent) {
6018		while (node) {
6019			if (node == parent) {
6020				return true;
6021			}
6022			node = node.parentNode;
6023		}
6024		return false;
6025	}
6026
6027	/**
6028	 * small indexOf wrapper
6029	 * @param {String} str
6030	 * @param {String} find
6031	 * @returns {Boolean} found
6032	 */
6033	function inStr(str, find) {
6034		return str.indexOf(find) > -1;
6035	}
6036
6037	/**
6038	 * split string on whitespace
6039	 * @param {String} str
6040	 * @returns {Array} words
6041	 */
6042	function splitStr(str) {
6043		return str.trim().split(/\s+/g);
6044	}
6045
6046	/**
6047	 * find if a array contains the object using indexOf or a simple polyFill
6048	 * @param {Array} src
6049	 * @param {String} find
6050	 * @param {String} [findByKey]
6051	 * @return {Boolean|Number} false when not found, or the index
6052	 */
6053	function inArray(src, find, findByKey) {
6054		if (src.indexOf && !findByKey) {
6055			return src.indexOf(find);
6056		} else {
6057			var i = 0;
6058			while (i < src.length) {
6059				if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {
6060					return i;
6061				}
6062				i++;
6063			}
6064			return -1;
6065		}
6066	}
6067
6068	/**
6069	 * convert array-like objects to real arrays
6070	 * @param {Object} obj
6071	 * @returns {Array}
6072	 */
6073	function toArray(obj) {
6074		return Array.prototype.slice.call(obj, 0);
6075	}
6076
6077	/**
6078	 * unique array with objects based on a key (like 'id') or just by the array's value
6079	 * @param {Array} src [{id:1},{id:2},{id:1}]
6080	 * @param {String} [key]
6081	 * @param {Boolean} [sort=False]
6082	 * @returns {Array} [{id:1},{id:2}]
6083	 */
6084	function uniqueArray(src, key, sort) {
6085		var results = [];
6086		var values = [];
6087		var i = 0;
6088
6089		while (i < src.length) {
6090			var val = key ? src[i][key] : src[i];
6091			if (inArray(values, val) < 0) {
6092				results.push(src[i]);
6093			}
6094			values[i] = val;
6095			i++;
6096		}
6097
6098		if (sort) {
6099			if (!key) {
6100				results = results.sort();
6101			} else {
6102				results = results.sort(function sortUniqueArray(a, b) {
6103					return a[key] > b[key];
6104				});
6105			}
6106		}
6107
6108		return results;
6109	}
6110
6111	/**
6112	 * get the prefixed property
6113	 * @param {Object} obj
6114	 * @param {String} property
6115	 * @returns {String|Undefined} prefixed
6116	 */
6117	function prefixed(obj, property) {
6118		var prefix, prop;
6119		var camelProp = property[0].toUpperCase() + property.slice(1);
6120
6121		var i = 0;
6122		while (i < VENDOR_PREFIXES.length) {
6123			prefix = VENDOR_PREFIXES[i];
6124			prop = (prefix) ? prefix + camelProp : property;
6125
6126			if (prop in obj) {
6127				return prop;
6128			}
6129			i++;
6130		}
6131		return undefined;
6132	}
6133
6134	/**
6135	 * get a unique id
6136	 * @returns {number} uniqueId
6137	 */
6138	var _uniqueId = 1;
6139	function uniqueId() {
6140		return _uniqueId++;
6141	}
6142
6143	/**
6144	 * get the window object of an element
6145	 * @param {HTMLElement} element
6146	 * @returns {DocumentView|Window}
6147	 */
6148	function getWindowForElement(element) {
6149		var doc = element.ownerDocument || element;
6150		return (doc.defaultView || doc.parentWindow || window);
6151	}
6152
6153	var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
6154
6155	var SUPPORT_TOUCH = ('ontouchstart' in window);
6156	var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;
6157	var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
6158
6159	var INPUT_TYPE_TOUCH = 'touch';
6160	var INPUT_TYPE_PEN = 'pen';
6161	var INPUT_TYPE_MOUSE = 'mouse';
6162	var INPUT_TYPE_KINECT = 'kinect';
6163
6164	var COMPUTE_INTERVAL = 25;
6165
6166	var INPUT_START = 1;
6167	var INPUT_MOVE = 2;
6168	var INPUT_END = 4;
6169	var INPUT_CANCEL = 8;
6170
6171	var DIRECTION_NONE = 1;
6172	var DIRECTION_LEFT = 2;
6173	var DIRECTION_RIGHT = 4;
6174	var DIRECTION_UP = 8;
6175	var DIRECTION_DOWN = 16;
6176
6177	var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
6178	var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
6179	var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
6180
6181	var PROPS_XY = ['x', 'y'];
6182	var PROPS_CLIENT_XY = ['clientX', 'clientY'];
6183
6184	/**
6185	 * create new input type manager
6186	 * @param {Manager} manager
6187	 * @param {Function} callback
6188	 * @returns {Input}
6189	 * @constructor
6190	 */
6191	function Input(manager, callback) {
6192		var self = this;
6193		this.manager = manager;
6194		this.callback = callback;
6195		this.element = manager.element;
6196		this.target = manager.options.inputTarget;
6197
6198		// smaller wrapper around the handler, for the scope and the enabled state of the manager,
6199		// so when disabled the input events are completely bypassed.
6200		this.domHandler = function(ev) {
6201			if (boolOrFn(manager.options.enable, [manager])) {
6202				self.handler(ev);
6203			}
6204		};
6205
6206		this.init();
6207
6208	}
6209
6210	Input.prototype = {
6211		/**
6212		 * should handle the inputEvent data and trigger the callback
6213		 * @virtual
6214		 */
6215		handler: function() { },
6216
6217		/**
6218		 * bind the events
6219		 */
6220		init: function() {
6221			this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
6222			this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
6223			this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
6224		},
6225
6226		/**
6227		 * unbind the events
6228		 */
6229		destroy: function() {
6230			this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
6231			this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
6232			this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
6233		}
6234	};
6235
6236	/**
6237	 * create new input type manager
6238	 * called by the Manager constructor
6239	 * @param {Hammer} manager
6240	 * @returns {Input}
6241	 */
6242	function createInputInstance(manager) {
6243		var Type;
6244		var inputClass = manager.options.inputClass;
6245
6246		if (inputClass) {
6247			Type = inputClass;
6248		} else if (SUPPORT_POINTER_EVENTS) {
6249			Type = PointerEventInput;
6250		} else if (SUPPORT_ONLY_TOUCH) {
6251			Type = TouchInput;
6252		} else if (!SUPPORT_TOUCH) {
6253			Type = MouseInput;
6254		} else {
6255			Type = TouchMouseInput;
6256		}
6257		return new (Type)(manager, inputHandler);
6258	}
6259
6260	/**
6261	 * handle input events
6262	 * @param {Manager} manager
6263	 * @param {String} eventType
6264	 * @param {Object} input
6265	 */
6266	function inputHandler(manager, eventType, input) {
6267		var pointersLen = input.pointers.length;
6268		var changedPointersLen = input.changedPointers.length;
6269		var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));
6270		var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));
6271
6272		input.isFirst = !!isFirst;
6273		input.isFinal = !!isFinal;
6274
6275		if (isFirst) {
6276			manager.session = {};
6277		}
6278
6279		// source event is the normalized value of the domEvents
6280		// like 'touchstart, mouseup, pointerdown'
6281		input.eventType = eventType;
6282
6283		// compute scale, rotation etc
6284		computeInputData(manager, input);
6285
6286		// emit secret event
6287		manager.emit('hammer.input', input);
6288
6289		manager.recognize(input);
6290		manager.session.prevInput = input;
6291	}
6292
6293	/**
6294	 * extend the data with some usable properties like scale, rotate, velocity etc
6295	 * @param {Object} manager
6296	 * @param {Object} input
6297	 */
6298	function computeInputData(manager, input) {
6299		var session = manager.session;
6300		var pointers = input.pointers;
6301		var pointersLength = pointers.length;
6302
6303		// store the first input to calculate the distance and direction
6304		if (!session.firstInput) {
6305			session.firstInput = simpleCloneInputData(input);
6306		}
6307
6308		// to compute scale and rotation we need to store the multiple touches
6309		if (pointersLength > 1 && !session.firstMultiple) {
6310			session.firstMultiple = simpleCloneInputData(input);
6311		} else if (pointersLength === 1) {
6312			session.firstMultiple = false;
6313		}
6314
6315		var firstInput = session.firstInput;
6316		var firstMultiple = session.firstMultiple;
6317		var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
6318
6319		var center = input.center = getCenter(pointers);
6320		input.timeStamp = now();
6321		input.deltaTime = input.timeStamp - firstInput.timeStamp;
6322
6323		input.angle = getAngle(offsetCenter, center);
6324		input.distance = getDistance(offsetCenter, center);
6325
6326		computeDeltaXY(session, input);
6327		input.offsetDirection = getDirection(input.deltaX, input.deltaY);
6328
6329		var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
6330		input.overallVelocityX = overallVelocity.x;
6331		input.overallVelocityY = overallVelocity.y;
6332		input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;
6333
6334		input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
6335		input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
6336
6337		input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >
6338			session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);
6339
6340		computeIntervalInputData(session, input);
6341
6342		// find the correct target
6343		var target = manager.element;
6344		if (hasParent(input.srcEvent.target, target)) {
6345			target = input.srcEvent.target;
6346		}
6347		input.target = target;
6348	}
6349
6350	function computeDeltaXY(session, input) {
6351		var center = input.center;
6352		var offset = session.offsetDelta || {};
6353		var prevDelta = session.prevDelta || {};
6354		var prevInput = session.prevInput || {};
6355
6356		if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
6357			prevDelta = session.prevDelta = {
6358				x: prevInput.deltaX || 0,
6359				y: prevInput.deltaY || 0
6360			};
6361
6362			offset = session.offsetDelta = {
6363				x: center.x,
6364				y: center.y
6365			};
6366		}
6367
6368		input.deltaX = prevDelta.x + (center.x - offset.x);
6369		input.deltaY = prevDelta.y + (center.y - offset.y);
6370	}
6371
6372	/**
6373	 * velocity is calculated every x ms
6374	 * @param {Object} session
6375	 * @param {Object} input
6376	 */
6377	function computeIntervalInputData(session, input) {
6378		var last = session.lastInterval || input,
6379			deltaTime = input.timeStamp - last.timeStamp,
6380			velocity, velocityX, velocityY, direction;
6381
6382		if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
6383			var deltaX = input.deltaX - last.deltaX;
6384			var deltaY = input.deltaY - last.deltaY;
6385
6386			var v = getVelocity(deltaTime, deltaX, deltaY);
6387			velocityX = v.x;
6388			velocityY = v.y;
6389			velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;
6390			direction = getDirection(deltaX, deltaY);
6391
6392			session.lastInterval = input;
6393		} else {
6394			// use latest velocity info if it doesn't overtake a minimum period
6395			velocity = last.velocity;
6396			velocityX = last.velocityX;
6397			velocityY = last.velocityY;
6398			direction = last.direction;
6399		}
6400
6401		input.velocity = velocity;
6402		input.velocityX = velocityX;
6403		input.velocityY = velocityY;
6404		input.direction = direction;
6405	}
6406
6407	/**
6408	 * create a simple clone from the input used for storage of firstInput and firstMultiple
6409	 * @param {Object} input
6410	 * @returns {Object} clonedInputData
6411	 */
6412	function simpleCloneInputData(input) {
6413		// make a simple copy of the pointers because we will get a reference if we don't
6414		// we only need clientXY for the calculations
6415		var pointers = [];
6416		var i = 0;
6417		while (i < input.pointers.length) {
6418			pointers[i] = {
6419				clientX: round(input.pointers[i].clientX),
6420				clientY: round(input.pointers[i].clientY)
6421			};
6422			i++;
6423		}
6424
6425		return {
6426			timeStamp: now(),
6427			pointers: pointers,
6428			center: getCenter(pointers),
6429			deltaX: input.deltaX,
6430			deltaY: input.deltaY
6431		};
6432	}
6433
6434	/**
6435	 * get the center of all the pointers
6436	 * @param {Array} pointers
6437	 * @return {Object} center contains `x` and `y` properties
6438	 */
6439	function getCenter(pointers) {
6440		var pointersLength = pointers.length;
6441
6442		// no need to loop when only one touch
6443		if (pointersLength === 1) {
6444			return {
6445				x: round(pointers[0].clientX),
6446				y: round(pointers[0].clientY)
6447			};
6448		}
6449
6450		var x = 0, y = 0, i = 0;
6451		while (i < pointersLength) {
6452			x += pointers[i].clientX;
6453			y += pointers[i].clientY;
6454			i++;
6455		}
6456
6457		return {
6458			x: round(x / pointersLength),
6459			y: round(y / pointersLength)
6460		};
6461	}
6462
6463	/**
6464	 * calculate the velocity between two points. unit is in px per ms.
6465	 * @param {Number} deltaTime
6466	 * @param {Number} x
6467	 * @param {Number} y
6468	 * @return {Object} velocity `x` and `y`
6469	 */
6470	function getVelocity(deltaTime, x, y) {
6471		return {
6472			x: x / deltaTime || 0,
6473			y: y / deltaTime || 0
6474		};
6475	}
6476
6477	/**
6478	 * get the direction between two points
6479	 * @param {Number} x
6480	 * @param {Number} y
6481	 * @return {Number} direction
6482	 */
6483	function getDirection(x, y) {
6484		if (x === y) {
6485			return DIRECTION_NONE;
6486		}
6487
6488		if (abs(x) >= abs(y)) {
6489			return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
6490		}
6491		return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
6492	}
6493
6494	/**
6495	 * calculate the absolute distance between two points
6496	 * @param {Object} p1 {x, y}
6497	 * @param {Object} p2 {x, y}
6498	 * @param {Array} [props] containing x and y keys
6499	 * @return {Number} distance
6500	 */
6501	function getDistance(p1, p2, props) {
6502		if (!props) {
6503			props = PROPS_XY;
6504		}
6505		var x = p2[props[0]] - p1[props[0]],
6506			y = p2[props[1]] - p1[props[1]];
6507
6508		return Math.sqrt((x * x) + (y * y));
6509	}
6510
6511	/**
6512	 * calculate the angle between two coordinates
6513	 * @param {Object} p1
6514	 * @param {Object} p2
6515	 * @param {Array} [props] containing x and y keys
6516	 * @return {Number} angle
6517	 */
6518	function getAngle(p1, p2, props) {
6519		if (!props) {
6520			props = PROPS_XY;
6521		}
6522		var x = p2[props[0]] - p1[props[0]],
6523			y = p2[props[1]] - p1[props[1]];
6524		return Math.atan2(y, x) * 180 / Math.PI;
6525	}
6526
6527	/**
6528	 * calculate the rotation degrees between two pointersets
6529	 * @param {Array} start array of pointers
6530	 * @param {Array} end array of pointers
6531	 * @return {Number} rotation
6532	 */
6533	function getRotation(start, end) {
6534		return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
6535	}
6536
6537	/**
6538	 * calculate the scale factor between two pointersets
6539	 * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
6540	 * @param {Array} start array of pointers
6541	 * @param {Array} end array of pointers
6542	 * @return {Number} scale
6543	 */
6544	function getScale(start, end) {
6545		return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
6546	}
6547
6548	var MOUSE_INPUT_MAP = {
6549		mousedown: INPUT_START,
6550		mousemove: INPUT_MOVE,
6551		mouseup: INPUT_END
6552	};
6553
6554	var MOUSE_ELEMENT_EVENTS = 'mousedown';
6555	var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
6556
6557	/**
6558	 * Mouse events input
6559	 * @constructor
6560	 * @extends Input
6561	 */
6562	function MouseInput() {
6563		this.evEl = MOUSE_ELEMENT_EVENTS;
6564		this.evWin = MOUSE_WINDOW_EVENTS;
6565
6566		this.pressed = false; // mousedown state
6567
6568		Input.apply(this, arguments);
6569	}
6570
6571	inherit(MouseInput, Input, {
6572		/**
6573		 * handle mouse events
6574		 * @param {Object} ev
6575		 */
6576		handler: function MEhandler(ev) {
6577			var eventType = MOUSE_INPUT_MAP[ev.type];
6578
6579			// on start we want to have the left mouse button down
6580			if (eventType & INPUT_START && ev.button === 0) {
6581				this.pressed = true;
6582			}
6583
6584			if (eventType & INPUT_MOVE && ev.which !== 1) {
6585				eventType = INPUT_END;
6586			}
6587
6588			// mouse must be down
6589			if (!this.pressed) {
6590				return;
6591			}
6592
6593			if (eventType & INPUT_END) {
6594				this.pressed = false;
6595			}
6596
6597			this.callback(this.manager, eventType, {
6598				pointers: [ev],
6599				changedPointers: [ev],
6600				pointerType: INPUT_TYPE_MOUSE,
6601				srcEvent: ev
6602			});
6603		}
6604	});
6605
6606	var POINTER_INPUT_MAP = {
6607		pointerdown: INPUT_START,
6608		pointermove: INPUT_MOVE,
6609		pointerup: INPUT_END,
6610		pointercancel: INPUT_CANCEL,
6611		pointerout: INPUT_CANCEL
6612	};
6613
6614// in IE10 the pointer types is defined as an enum
6615	var IE10_POINTER_TYPE_ENUM = {
6616		2: INPUT_TYPE_TOUCH,
6617		3: INPUT_TYPE_PEN,
6618		4: INPUT_TYPE_MOUSE,
6619		5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
6620	};
6621
6622	var POINTER_ELEMENT_EVENTS = 'pointerdown';
6623	var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';
6624
6625// IE10 has prefixed support, and case-sensitive
6626	if (window.MSPointerEvent && !window.PointerEvent) {
6627		POINTER_ELEMENT_EVENTS = 'MSPointerDown';
6628		POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
6629	}
6630
6631	/**
6632	 * Pointer events input
6633	 * @constructor
6634	 * @extends Input
6635	 */
6636	function PointerEventInput() {
6637		this.evEl = POINTER_ELEMENT_EVENTS;
6638		this.evWin = POINTER_WINDOW_EVENTS;
6639
6640		Input.apply(this, arguments);
6641
6642		this.store = (this.manager.session.pointerEvents = []);
6643	}
6644
6645	inherit(PointerEventInput, Input, {
6646		/**
6647		 * handle mouse events
6648		 * @param {Object} ev
6649		 */
6650		handler: function PEhandler(ev) {
6651			var store = this.store;
6652			var removePointer = false;
6653
6654			var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
6655			var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
6656			var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
6657
6658			var isTouch = (pointerType == INPUT_TYPE_TOUCH);
6659
6660			// get index of the event in the store
6661			var storeIndex = inArray(store, ev.pointerId, 'pointerId');
6662
6663			// start and mouse must be down
6664			if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
6665				if (storeIndex < 0) {
6666					store.push(ev);
6667					storeIndex = store.length - 1;
6668				}
6669			} else if (eventType & (INPUT_END | INPUT_CANCEL)) {
6670				removePointer = true;
6671			}
6672
6673			// it not found, so the pointer hasn't been down (so it's probably a hover)
6674			if (storeIndex < 0) {
6675				return;
6676			}
6677
6678			// update the event in the store
6679			store[storeIndex] = ev;
6680
6681			this.callback(this.manager, eventType, {
6682				pointers: store,
6683				changedPointers: [ev],
6684				pointerType: pointerType,
6685				srcEvent: ev
6686			});
6687
6688			if (removePointer) {
6689				// remove from the store
6690				store.splice(storeIndex, 1);
6691			}
6692		}
6693	});
6694
6695	var SINGLE_TOUCH_INPUT_MAP = {
6696		touchstart: INPUT_START,
6697		touchmove: INPUT_MOVE,
6698		touchend: INPUT_END,
6699		touchcancel: INPUT_CANCEL
6700	};
6701
6702	var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
6703	var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
6704
6705	/**
6706	 * Touch events input
6707	 * @constructor
6708	 * @extends Input
6709	 */
6710	function SingleTouchInput() {
6711		this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
6712		this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
6713		this.started = false;
6714
6715		Input.apply(this, arguments);
6716	}
6717
6718	inherit(SingleTouchInput, Input, {
6719		handler: function TEhandler(ev) {
6720			var type = SINGLE_TOUCH_INPUT_MAP[ev.type];
6721
6722			// should we handle the touch events?
6723			if (type === INPUT_START) {
6724				this.started = true;
6725			}
6726
6727			if (!this.started) {
6728				return;
6729			}
6730
6731			var touches = normalizeSingleTouches.call(this, ev, type);
6732
6733			// when done, reset the started state
6734			if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
6735				this.started = false;
6736			}
6737
6738			this.callback(this.manager, type, {
6739				pointers: touches[0],
6740				changedPointers: touches[1],
6741				pointerType: INPUT_TYPE_TOUCH,
6742				srcEvent: ev
6743			});
6744		}
6745	});
6746
6747	/**
6748	 * @this {TouchInput}
6749	 * @param {Object} ev
6750	 * @param {Number} type flag
6751	 * @returns {undefined|Array} [all, changed]
6752	 */
6753	function normalizeSingleTouches(ev, type) {
6754		var all = toArray(ev.touches);
6755		var changed = toArray(ev.changedTouches);
6756
6757		if (type & (INPUT_END | INPUT_CANCEL)) {
6758			all = uniqueArray(all.concat(changed), 'identifier', true);
6759		}
6760
6761		return [all, changed];
6762	}
6763
6764	var TOUCH_INPUT_MAP = {
6765		touchstart: INPUT_START,
6766		touchmove: INPUT_MOVE,
6767		touchend: INPUT_END,
6768		touchcancel: INPUT_CANCEL
6769	};
6770
6771	var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
6772
6773	/**
6774	 * Multi-user touch events input
6775	 * @constructor
6776	 * @extends Input
6777	 */
6778	function TouchInput() {
6779		this.evTarget = TOUCH_TARGET_EVENTS;
6780		this.targetIds = {};
6781
6782		Input.apply(this, arguments);
6783	}
6784
6785	inherit(TouchInput, Input, {
6786		handler: function MTEhandler(ev) {
6787			var type = TOUCH_INPUT_MAP[ev.type];
6788			var touches = getTouches.call(this, ev, type);
6789			if (!touches) {
6790				return;
6791			}
6792
6793			this.callback(this.manager, type, {
6794				pointers: touches[0],
6795				changedPointers: touches[1],
6796				pointerType: INPUT_TYPE_TOUCH,
6797				srcEvent: ev
6798			});
6799		}
6800	});
6801
6802	/**
6803	 * @this {TouchInput}
6804	 * @param {Object} ev
6805	 * @param {Number} type flag
6806	 * @returns {undefined|Array} [all, changed]
6807	 */
6808	function getTouches(ev, type) {
6809		var allTouches = toArray(ev.touches);
6810		var targetIds = this.targetIds;
6811
6812		// when there is only one touch, the process can be simplified
6813		if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
6814			targetIds[allTouches[0].identifier] = true;
6815			return [allTouches, allTouches];
6816		}
6817
6818		var i,
6819			targetTouches,
6820			changedTouches = toArray(ev.changedTouches),
6821			changedTargetTouches = [],
6822			target = this.target;
6823
6824		// get target touches from touches
6825		targetTouches = allTouches.filter(function(touch) {
6826			return hasParent(touch.target, target);
6827		});
6828
6829		// collect touches
6830		if (type === INPUT_START) {
6831			i = 0;
6832			while (i < targetTouches.length) {
6833				targetIds[targetTouches[i].identifier] = true;
6834				i++;
6835			}
6836		}
6837
6838		// filter changed touches to only contain touches that exist in the collected target ids
6839		i = 0;
6840		while (i < changedTouches.length) {
6841			if (targetIds[changedTouches[i].identifier]) {
6842				changedTargetTouches.push(changedTouches[i]);
6843			}
6844
6845			// cleanup removed touches
6846			if (type & (INPUT_END | INPUT_CANCEL)) {
6847				delete targetIds[changedTouches[i].identifier];
6848			}
6849			i++;
6850		}
6851
6852		if (!changedTargetTouches.length) {
6853			return;
6854		}
6855
6856		return [
6857			// merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
6858			uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),
6859			changedTargetTouches
6860		];
6861	}
6862
6863	/**
6864	 * Combined touch and mouse input
6865	 *
6866	 * Touch has a higher priority then mouse, and while touching no mouse events are allowed.
6867	 * This because touch devices also emit mouse events while doing a touch.
6868	 *
6869	 * @constructor
6870	 * @extends Input
6871	 */
6872
6873	var DEDUP_TIMEOUT = 2500;
6874	var DEDUP_DISTANCE = 25;
6875
6876	function TouchMouseInput() {
6877		Input.apply(this, arguments);
6878
6879		var handler = bindFn(this.handler, this);
6880		this.touch = new TouchInput(this.manager, handler);
6881		this.mouse = new MouseInput(this.manager, handler);
6882
6883		this.primaryTouch = null;
6884		this.lastTouches = [];
6885	}
6886
6887	inherit(TouchMouseInput, Input, {
6888		/**
6889		 * handle mouse and touch events
6890		 * @param {Hammer} manager
6891		 * @param {String} inputEvent
6892		 * @param {Object} inputData
6893		 */
6894		handler: function TMEhandler(manager, inputEvent, inputData) {
6895			var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH),
6896				isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);
6897
6898			if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {
6899				return;
6900			}
6901
6902			// when we're in a touch event, record touches to  de-dupe synthetic mouse event
6903			if (isTouch) {
6904				recordTouches.call(this, inputEvent, inputData);
6905			} else if (isMouse && isSyntheticEvent.call(this, inputData)) {
6906				return;
6907			}
6908
6909			this.callback(manager, inputEvent, inputData);
6910		},
6911
6912		/**
6913		 * remove the event listeners
6914		 */
6915		destroy: function destroy() {
6916			this.touch.destroy();
6917			this.mouse.destroy();
6918		}
6919	});
6920
6921	function recordTouches(eventType, eventData) {
6922		if (eventType & INPUT_START) {
6923			this.primaryTouch = eventData.changedPointers[0].identifier;
6924			setLastTouch.call(this, eventData);
6925		} else if (eventType & (INPUT_END | INPUT_CANCEL)) {
6926			setLastTouch.call(this, eventData);
6927		}
6928	}
6929
6930	function setLastTouch(eventData) {
6931		var touch = eventData.changedPointers[0];
6932
6933		if (touch.identifier === this.primaryTouch) {
6934			var lastTouch = {x: touch.clientX, y: touch.clientY};
6935			this.lastTouches.push(lastTouch);
6936			var lts = this.lastTouches;
6937			var removeLastTouch = function() {
6938				var i = lts.indexOf(lastTouch);
6939				if (i > -1) {
6940					lts.splice(i, 1);
6941				}
6942			};
6943			setTimeout(removeLastTouch, DEDUP_TIMEOUT);
6944		}
6945	}
6946
6947	function isSyntheticEvent(eventData) {
6948		var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY;
6949		for (var i = 0; i < this.lastTouches.length; i++) {
6950			var t = this.lastTouches[i];
6951			var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);
6952			if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {
6953				return true;
6954			}
6955		}
6956		return false;
6957	}
6958
6959	var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
6960	var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
6961
6962// magical touchAction value
6963	var TOUCH_ACTION_COMPUTE = 'compute';
6964	var TOUCH_ACTION_AUTO = 'auto';
6965	var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
6966	var TOUCH_ACTION_NONE = 'none';
6967	var TOUCH_ACTION_PAN_X = 'pan-x';
6968	var TOUCH_ACTION_PAN_Y = 'pan-y';
6969	var TOUCH_ACTION_MAP = getTouchActionProps();
6970
6971	/**
6972	 * Touch Action
6973	 * sets the touchAction property or uses the js alternative
6974	 * @param {Manager} manager
6975	 * @param {String} value
6976	 * @constructor
6977	 */
6978	function TouchAction(manager, value) {
6979		this.manager = manager;
6980		this.set(value);
6981	}
6982
6983	TouchAction.prototype = {
6984		/**
6985		 * set the touchAction value on the element or enable the polyfill
6986		 * @param {String} value
6987		 */
6988		set: function(value) {
6989			// find out the touch-action by the event handlers
6990			if (value == TOUCH_ACTION_COMPUTE) {
6991				value = this.compute();
6992			}
6993
6994			if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
6995				this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
6996			}
6997			this.actions = value.toLowerCase().trim();
6998		},
6999
7000		/**
7001		 * just re-set the touchAction value
7002		 */
7003		update: function() {
7004			this.set(this.manager.options.touchAction);
7005		},
7006
7007		/**
7008		 * compute the value for the touchAction property based on the recognizer's settings
7009		 * @returns {String} value
7010		 */
7011		compute: function() {
7012			var actions = [];
7013			each(this.manager.recognizers, function(recognizer) {
7014				if (boolOrFn(recognizer.options.enable, [recognizer])) {
7015					actions = actions.concat(recognizer.getTouchAction());
7016				}
7017			});
7018			return cleanTouchActions(actions.join(' '));
7019		},
7020
7021		/**
7022		 * this method is called on each input cycle and provides the preventing of the browser behavior
7023		 * @param {Object} input
7024		 */
7025		preventDefaults: function(input) {
7026			var srcEvent = input.srcEvent;
7027			var direction = input.offsetDirection;
7028
7029			// if the touch action did prevented once this session
7030			if (this.manager.session.prevented) {
7031				srcEvent.preventDefault();
7032				return;
7033			}
7034
7035			var actions = this.actions;
7036			var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
7037			var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
7038			var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];
7039
7040			if (hasNone) {
7041				//do not prevent defaults if this is a tap gesture
7042
7043				var isTapPointer = input.pointers.length === 1;
7044				var isTapMovement = input.distance < 2;
7045				var isTapTouchTime = input.deltaTime < 250;
7046
7047				if (isTapPointer && isTapMovement && isTapTouchTime) {
7048					return;
7049				}
7050			}
7051
7052			if (hasPanX && hasPanY) {
7053				// `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
7054				return;
7055			}
7056
7057			if (hasNone ||
7058				(hasPanY && direction & DIRECTION_HORIZONTAL) ||
7059				(hasPanX && direction & DIRECTION_VERTICAL)) {
7060				return this.preventSrc(srcEvent);
7061			}
7062		},
7063
7064		/**
7065		 * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
7066		 * @param {Object} srcEvent
7067		 */
7068		preventSrc: function(srcEvent) {
7069			this.manager.session.prevented = true;
7070			srcEvent.preventDefault();
7071		}
7072	};
7073
7074	/**
7075	 * when the touchActions are collected they are not a valid value, so we need to clean things up. *
7076	 * @param {String} actions
7077	 * @returns {*}
7078	 */
7079	function cleanTouchActions(actions) {
7080		// none
7081		if (inStr(actions, TOUCH_ACTION_NONE)) {
7082			return TOUCH_ACTION_NONE;
7083		}
7084
7085		var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
7086		var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
7087
7088		// if both pan-x and pan-y are set (different recognizers
7089		// for different directions, e.g. horizontal pan but vertical swipe?)
7090		// we need none (as otherwise with pan-x pan-y combined none of these
7091		// recognizers will work, since the browser would handle all panning
7092		if (hasPanX && hasPanY) {
7093			return TOUCH_ACTION_NONE;
7094		}
7095
7096		// pan-x OR pan-y
7097		if (hasPanX || hasPanY) {
7098			return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
7099		}
7100
7101		// manipulation
7102		if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
7103			return TOUCH_ACTION_MANIPULATION;
7104		}
7105
7106		return TOUCH_ACTION_AUTO;
7107	}
7108
7109	function getTouchActionProps() {
7110		if (!NATIVE_TOUCH_ACTION) {
7111			return false;
7112		}
7113		var touchMap = {};
7114		var cssSupports = window.CSS && window.CSS.supports;
7115		['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function(val) {
7116
7117			// If css.supports is not supported but there is native touch-action assume it supports
7118			// all values. This is the case for IE 10 and 11.
7119			touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;
7120		});
7121		return touchMap;
7122	}
7123
7124	/**
7125	 * Recognizer flow explained; *
7126	 * All recognizers have the initial state of POSSIBLE when a input session starts.
7127	 * The definition of a input session is from the first input until the last input, with all it's movement in it. *
7128	 * Example session for mouse-input: mousedown -> mousemove -> mouseup
7129	 *
7130	 * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
7131	 * which determines with state it should be.
7132	 *
7133	 * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
7134	 * POSSIBLE to give it another change on the next cycle.
7135	 *
7136	 *               Possible
7137	 *                  |
7138	 *            +-----+---------------+
7139	 *            |                     |
7140	 *      +-----+-----+               |
7141	 *      |           |               |
7142	 *   Failed      Cancelled          |
7143	 *                          +-------+------+
7144	 *                          |              |
7145	 *                      Recognized       Began
7146	 *                                         |
7147	 *                                      Changed
7148	 *                                         |
7149	 *                                  Ended/Recognized
7150	 */
7151	var STATE_POSSIBLE = 1;
7152	var STATE_BEGAN = 2;
7153	var STATE_CHANGED = 4;
7154	var STATE_ENDED = 8;
7155	var STATE_RECOGNIZED = STATE_ENDED;
7156	var STATE_CANCELLED = 16;
7157	var STATE_FAILED = 32;
7158
7159	/**
7160	 * Recognizer
7161	 * Every recognizer needs to extend from this class.
7162	 * @constructor
7163	 * @param {Object} options
7164	 */
7165	function Recognizer(options) {
7166		this.options = assign({}, this.defaults, options || {});
7167
7168		this.id = uniqueId();
7169
7170		this.manager = null;
7171
7172		// default is enable true
7173		this.options.enable = ifUndefined(this.options.enable, true);
7174
7175		this.state = STATE_POSSIBLE;
7176
7177		this.simultaneous = {};
7178		this.requireFail = [];
7179	}
7180
7181	Recognizer.prototype = {
7182		/**
7183		 * @virtual
7184		 * @type {Object}
7185		 */
7186		defaults: {},
7187
7188		/**
7189		 * set options
7190		 * @param {Object} options
7191		 * @return {Recognizer}
7192		 */
7193		set: function(options) {
7194			assign(this.options, options);
7195
7196			// also update the touchAction, in case something changed about the directions/enabled state
7197			this.manager && this.manager.touchAction.update();
7198			return this;
7199		},
7200
7201		/**
7202		 * recognize simultaneous with an other recognizer.
7203		 * @param {Recognizer} otherRecognizer
7204		 * @returns {Recognizer} this
7205		 */
7206		recognizeWith: function(otherRecognizer) {
7207			if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
7208				return this;
7209			}
7210
7211			var simultaneous = this.simultaneous;
7212			otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
7213			if (!simultaneous[otherRecognizer.id]) {
7214				simultaneous[otherRecognizer.id] = otherRecognizer;
7215				otherRecognizer.recognizeWith(this);
7216			}
7217			return this;
7218		},
7219
7220		/**
7221		 * drop the simultaneous link. it doesnt remove the link on the other recognizer.
7222		 * @param {Recognizer} otherRecognizer
7223		 * @returns {Recognizer} this
7224		 */
7225		dropRecognizeWith: function(otherRecognizer) {
7226			if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
7227				return this;
7228			}
7229
7230			otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
7231			delete this.simultaneous[otherRecognizer.id];
7232			return this;
7233		},
7234
7235		/**
7236		 * recognizer can only run when an other is failing
7237		 * @param {Recognizer} otherRecognizer
7238		 * @returns {Recognizer} this
7239		 */
7240		requireFailure: function(otherRecognizer) {
7241			if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
7242				return this;
7243			}
7244
7245			var requireFail = this.requireFail;
7246			otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
7247			if (inArray(requireFail, otherRecognizer) === -1) {
7248				requireFail.push(otherRecognizer);
7249				otherRecognizer.requireFailure(this);
7250			}
7251			return this;
7252		},
7253
7254		/**
7255		 * drop the requireFailure link. it does not remove the link on the other recognizer.
7256		 * @param {Recognizer} otherRecognizer
7257		 * @returns {Recognizer} this
7258		 */
7259		dropRequireFailure: function(otherRecognizer) {
7260			if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
7261				return this;
7262			}
7263
7264			otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
7265			var index = inArray(this.requireFail, otherRecognizer);
7266			if (index > -1) {
7267				this.requireFail.splice(index, 1);
7268			}
7269			return this;
7270		},
7271
7272		/**
7273		 * has require failures boolean
7274		 * @returns {boolean}
7275		 */
7276		hasRequireFailures: function() {
7277			return this.requireFail.length > 0;
7278		},
7279
7280		/**
7281		 * if the recognizer can recognize simultaneous with an other recognizer
7282		 * @param {Recognizer} otherRecognizer
7283		 * @returns {Boolean}
7284		 */
7285		canRecognizeWith: function(otherRecognizer) {
7286			return !!this.simultaneous[otherRecognizer.id];
7287		},
7288
7289		/**
7290		 * You should use `tryEmit` instead of `emit` directly to check
7291		 * that all the needed recognizers has failed before emitting.
7292		 * @param {Object} input
7293		 */
7294		emit: function(input) {
7295			var self = this;
7296			var state = this.state;
7297
7298			function emit(event) {
7299				self.manager.emit(event, input);
7300			}
7301
7302			// 'panstart' and 'panmove'
7303			if (state < STATE_ENDED) {
7304				emit(self.options.event + stateStr(state));
7305			}
7306
7307			emit(self.options.event); // simple 'eventName' events
7308
7309			if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...)
7310				emit(input.additionalEvent);
7311			}
7312
7313			// panend and pancancel
7314			if (state >= STATE_ENDED) {
7315				emit(self.options.event + stateStr(state));
7316			}
7317		},
7318
7319		/**
7320		 * Check that all the require failure recognizers has failed,
7321		 * if true, it emits a gesture event,
7322		 * otherwise, setup the state to FAILED.
7323		 * @param {Object} input
7324		 */
7325		tryEmit: function(input) {
7326			if (this.canEmit()) {
7327				return this.emit(input);
7328			}
7329			// it's failing anyway
7330			this.state = STATE_FAILED;
7331		},
7332
7333		/**
7334		 * can we emit?
7335		 * @returns {boolean}
7336		 */
7337		canEmit: function() {
7338			var i = 0;
7339			while (i < this.requireFail.length) {
7340				if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
7341					return false;
7342				}
7343				i++;
7344			}
7345			return true;
7346		},
7347
7348		/**
7349		 * update the recognizer
7350		 * @param {Object} inputData
7351		 */
7352		recognize: function(inputData) {
7353			// make a new copy of the inputData
7354			// so we can change the inputData without messing up the other recognizers
7355			var inputDataClone = assign({}, inputData);
7356
7357			// is is enabled and allow recognizing?
7358			if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
7359				this.reset();
7360				this.state = STATE_FAILED;
7361				return;
7362			}
7363
7364			// reset when we've reached the end
7365			if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
7366				this.state = STATE_POSSIBLE;
7367			}
7368
7369			this.state = this.process(inputDataClone);
7370
7371			// the recognizer has recognized a gesture
7372			// so trigger an event
7373			if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
7374				this.tryEmit(inputDataClone);
7375			}
7376		},
7377
7378		/**
7379		 * return the state of the recognizer
7380		 * the actual recognizing happens in this method
7381		 * @virtual
7382		 * @param {Object} inputData
7383		 * @returns {Const} STATE
7384		 */
7385		process: function(inputData) { }, // jshint ignore:line
7386
7387		/**
7388		 * return the preferred touch-action
7389		 * @virtual
7390		 * @returns {Array}
7391		 */
7392		getTouchAction: function() { },
7393
7394		/**
7395		 * called when the gesture isn't allowed to recognize
7396		 * like when another is being recognized or it is disabled
7397		 * @virtual
7398		 */
7399		reset: function() { }
7400	};
7401
7402	/**
7403	 * get a usable string, used as event postfix
7404	 * @param {Const} state
7405	 * @returns {String} state
7406	 */
7407	function stateStr(state) {
7408		if (state & STATE_CANCELLED) {
7409			return 'cancel';
7410		} else if (state & STATE_ENDED) {
7411			return 'end';
7412		} else if (state & STATE_CHANGED) {
7413			return 'move';
7414		} else if (state & STATE_BEGAN) {
7415			return 'start';
7416		}
7417		return '';
7418	}
7419
7420	/**
7421	 * direction cons to string
7422	 * @param {Const} direction
7423	 * @returns {String}
7424	 */
7425	function directionStr(direction) {
7426		if (direction == DIRECTION_DOWN) {
7427			return 'down';
7428		} else if (direction == DIRECTION_UP) {
7429			return 'up';
7430		} else if (direction == DIRECTION_LEFT) {
7431			return 'left';
7432		} else if (direction == DIRECTION_RIGHT) {
7433			return 'right';
7434		}
7435		return '';
7436	}
7437
7438	/**
7439	 * get a recognizer by name if it is bound to a manager
7440	 * @param {Recognizer|String} otherRecognizer
7441	 * @param {Recognizer} recognizer
7442	 * @returns {Recognizer}
7443	 */
7444	function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
7445		var manager = recognizer.manager;
7446		if (manager) {
7447			return manager.get(otherRecognizer);
7448		}
7449		return otherRecognizer;
7450	}
7451
7452	/**
7453	 * This recognizer is just used as a base for the simple attribute recognizers.
7454	 * @constructor
7455	 * @extends Recognizer
7456	 */
7457	function AttrRecognizer() {
7458		Recognizer.apply(this, arguments);
7459	}
7460
7461	inherit(AttrRecognizer, Recognizer, {
7462		/**
7463		 * @namespace
7464		 * @memberof AttrRecognizer
7465		 */
7466		defaults: {
7467			/**
7468			 * @type {Number}
7469			 * @default 1
7470			 */
7471			pointers: 1
7472		},
7473
7474		/**
7475		 * Used to check if it the recognizer receives valid input, like input.distance > 10.
7476		 * @memberof AttrRecognizer
7477		 * @param {Object} input
7478		 * @returns {Boolean} recognized
7479		 */
7480		attrTest: function(input) {
7481			var optionPointers = this.options.pointers;
7482			return optionPointers === 0 || input.pointers.length === optionPointers;
7483		},
7484
7485		/**
7486		 * Process the input and return the state for the recognizer
7487		 * @memberof AttrRecognizer
7488		 * @param {Object} input
7489		 * @returns {*} State
7490		 */
7491		process: function(input) {
7492			var state = this.state;
7493			var eventType = input.eventType;
7494
7495			var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
7496			var isValid = this.attrTest(input);
7497
7498			// on cancel input and we've recognized before, return STATE_CANCELLED
7499			if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
7500				return state | STATE_CANCELLED;
7501			} else if (isRecognized || isValid) {
7502				if (eventType & INPUT_END) {
7503					return state | STATE_ENDED;
7504				} else if (!(state & STATE_BEGAN)) {
7505					return STATE_BEGAN;
7506				}
7507				return state | STATE_CHANGED;
7508			}
7509			return STATE_FAILED;
7510		}
7511	});
7512
7513	/**
7514	 * Pan
7515	 * Recognized when the pointer is down and moved in the allowed direction.
7516	 * @constructor
7517	 * @extends AttrRecognizer
7518	 */
7519	function PanRecognizer() {
7520		AttrRecognizer.apply(this, arguments);
7521
7522		this.pX = null;
7523		this.pY = null;
7524	}
7525
7526	inherit(PanRecognizer, AttrRecognizer, {
7527		/**
7528		 * @namespace
7529		 * @memberof PanRecognizer
7530		 */
7531		defaults: {
7532			event: 'pan',
7533			threshold: 10,
7534			pointers: 1,
7535			direction: DIRECTION_ALL
7536		},
7537
7538		getTouchAction: function() {
7539			var direction = this.options.direction;
7540			var actions = [];
7541			if (direction & DIRECTION_HORIZONTAL) {
7542				actions.push(TOUCH_ACTION_PAN_Y);
7543			}
7544			if (direction & DIRECTION_VERTICAL) {
7545				actions.push(TOUCH_ACTION_PAN_X);
7546			}
7547			return actions;
7548		},
7549
7550		directionTest: function(input) {
7551			var options = this.options;
7552			var hasMoved = true;
7553			var distance = input.distance;
7554			var direction = input.direction;
7555			var x = input.deltaX;
7556			var y = input.deltaY;
7557
7558			// lock to axis?
7559			if (!(direction & options.direction)) {
7560				if (options.direction & DIRECTION_HORIZONTAL) {
7561					direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;
7562					hasMoved = x != this.pX;
7563					distance = Math.abs(input.deltaX);
7564				} else {
7565					direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;
7566					hasMoved = y != this.pY;
7567					distance = Math.abs(input.deltaY);
7568				}
7569			}
7570			input.direction = direction;
7571			return hasMoved && distance > options.threshold && direction & options.direction;
7572		},
7573
7574		attrTest: function(input) {
7575			return AttrRecognizer.prototype.attrTest.call(this, input) &&
7576				(this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));
7577		},
7578
7579		emit: function(input) {
7580
7581			this.pX = input.deltaX;
7582			this.pY = input.deltaY;
7583
7584			var direction = directionStr(input.direction);
7585
7586			if (direction) {
7587				input.additionalEvent = this.options.event + direction;
7588			}
7589			this._super.emit.call(this, input);
7590		}
7591	});
7592
7593	/**
7594	 * Pinch
7595	 * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
7596	 * @constructor
7597	 * @extends AttrRecognizer
7598	 */
7599	function PinchRecognizer() {
7600		AttrRecognizer.apply(this, arguments);
7601	}
7602
7603	inherit(PinchRecognizer, AttrRecognizer, {
7604		/**
7605		 * @namespace
7606		 * @memberof PinchRecognizer
7607		 */
7608		defaults: {
7609			event: 'pinch',
7610			threshold: 0,
7611			pointers: 2
7612		},
7613
7614		getTouchAction: function() {
7615			return [TOUCH_ACTION_NONE];
7616		},
7617
7618		attrTest: function(input) {
7619			return this._super.attrTest.call(this, input) &&
7620				(Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
7621		},
7622
7623		emit: function(input) {
7624			if (input.scale !== 1) {
7625				var inOut = input.scale < 1 ? 'in' : 'out';
7626				input.additionalEvent = this.options.event + inOut;
7627			}
7628			this._super.emit.call(this, input);
7629		}
7630	});
7631
7632	/**
7633	 * Press
7634	 * Recognized when the pointer is down for x ms without any movement.
7635	 * @constructor
7636	 * @extends Recognizer
7637	 */
7638	function PressRecognizer() {
7639		Recognizer.apply(this, arguments);
7640
7641		this._timer = null;
7642		this._input = null;
7643	}
7644
7645	inherit(PressRecognizer, Recognizer, {
7646		/**
7647		 * @namespace
7648		 * @memberof PressRecognizer
7649		 */
7650		defaults: {
7651			event: 'press',
7652			pointers: 1,
7653			time: 251, // minimal time of the pointer to be pressed
7654			threshold: 9 // a minimal movement is ok, but keep it low
7655		},
7656
7657		getTouchAction: function() {
7658			return [TOUCH_ACTION_AUTO];
7659		},
7660
7661		process: function(input) {
7662			var options = this.options;
7663			var validPointers = input.pointers.length === options.pointers;
7664			var validMovement = input.distance < options.threshold;
7665			var validTime = input.deltaTime > options.time;
7666
7667			this._input = input;
7668
7669			// we only allow little movement
7670			// and we've reached an end event, so a tap is possible
7671			if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {
7672				this.reset();
7673			} else if (input.eventType & INPUT_START) {
7674				this.reset();
7675				this._timer = setTimeoutContext(function() {
7676					this.state = STATE_RECOGNIZED;
7677					this.tryEmit();
7678				}, options.time, this);
7679			} else if (input.eventType & INPUT_END) {
7680				return STATE_RECOGNIZED;
7681			}
7682			return STATE_FAILED;
7683		},
7684
7685		reset: function() {
7686			clearTimeout(this._timer);
7687		},
7688
7689		emit: function(input) {
7690			if (this.state !== STATE_RECOGNIZED) {
7691				return;
7692			}
7693
7694			if (input && (input.eventType & INPUT_END)) {
7695				this.manager.emit(this.options.event + 'up', input);
7696			} else {
7697				this._input.timeStamp = now();
7698				this.manager.emit(this.options.event, this._input);
7699			}
7700		}
7701	});
7702
7703	/**
7704	 * Rotate
7705	 * Recognized when two or more pointer are moving in a circular motion.
7706	 * @constructor
7707	 * @extends AttrRecognizer
7708	 */
7709	function RotateRecognizer() {
7710		AttrRecognizer.apply(this, arguments);
7711	}
7712
7713	inherit(RotateRecognizer, AttrRecognizer, {
7714		/**
7715		 * @namespace
7716		 * @memberof RotateRecognizer
7717		 */
7718		defaults: {
7719			event: 'rotate',
7720			threshold: 0,
7721			pointers: 2
7722		},
7723
7724		getTouchAction: function() {
7725			return [TOUCH_ACTION_NONE];
7726		},
7727
7728		attrTest: function(input) {
7729			return this._super.attrTest.call(this, input) &&
7730				(Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
7731		}
7732	});
7733
7734	/**
7735	 * Swipe
7736	 * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
7737	 * @constructor
7738	 * @extends AttrRecognizer
7739	 */
7740	function SwipeRecognizer() {
7741		AttrRecognizer.apply(this, arguments);
7742	}
7743
7744	inherit(SwipeRecognizer, AttrRecognizer, {
7745		/**
7746		 * @namespace
7747		 * @memberof SwipeRecognizer
7748		 */
7749		defaults: {
7750			event: 'swipe',
7751			threshold: 10,
7752			velocity: 0.3,
7753			direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
7754			pointers: 1
7755		},
7756
7757		getTouchAction: function() {
7758			return PanRecognizer.prototype.getTouchAction.call(this);
7759		},
7760
7761		attrTest: function(input) {
7762			var direction = this.options.direction;
7763			var velocity;
7764
7765			if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
7766				velocity = input.overallVelocity;
7767			} else if (direction & DIRECTION_HORIZONTAL) {
7768				velocity = input.overallVelocityX;
7769			} else if (direction & DIRECTION_VERTICAL) {
7770				velocity = input.overallVelocityY;
7771			}
7772
7773			return this._super.attrTest.call(this, input) &&
7774				direction & input.offsetDirection &&
7775				input.distance > this.options.threshold &&
7776				input.maxPointers == this.options.pointers &&
7777				abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
7778		},
7779
7780		emit: function(input) {
7781			var direction = directionStr(input.offsetDirection);
7782			if (direction) {
7783				this.manager.emit(this.options.event + direction, input);
7784			}
7785
7786			this.manager.emit(this.options.event, input);
7787		}
7788	});
7789
7790	/**
7791	 * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
7792	 * between the given interval and position. The delay option can be used to recognize multi-taps without firing
7793	 * a single tap.
7794	 *
7795	 * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
7796	 * multi-taps being recognized.
7797	 * @constructor
7798	 * @extends Recognizer
7799	 */
7800	function TapRecognizer() {
7801		Recognizer.apply(this, arguments);
7802
7803		// previous time and center,
7804		// used for tap counting
7805		this.pTime = false;
7806		this.pCenter = false;
7807
7808		this._timer = null;
7809		this._input = null;
7810		this.count = 0;
7811	}
7812
7813	inherit(TapRecognizer, Recognizer, {
7814		/**
7815		 * @namespace
7816		 * @memberof PinchRecognizer
7817		 */
7818		defaults: {
7819			event: 'tap',
7820			pointers: 1,
7821			taps: 1,
7822			interval: 300, // max time between the multi-tap taps
7823			time: 250, // max time of the pointer to be down (like finger on the screen)
7824			threshold: 9, // a minimal movement is ok, but keep it low
7825			posThreshold: 10 // a multi-tap can be a bit off the initial position
7826		},
7827
7828		getTouchAction: function() {
7829			return [TOUCH_ACTION_MANIPULATION];
7830		},
7831
7832		process: function(input) {
7833			var options = this.options;
7834
7835			var validPointers = input.pointers.length === options.pointers;
7836			var validMovement = input.distance < options.threshold;
7837			var validTouchTime = input.deltaTime < options.time;
7838
7839			this.reset();
7840
7841			if ((input.eventType & INPUT_START) && (this.count === 0)) {
7842				return this.failTimeout();
7843			}
7844
7845			// we only allow little movement
7846			// and we've reached an end event, so a tap is possible
7847			if (validMovement && validTouchTime && validPointers) {
7848				if (input.eventType != INPUT_END) {
7849					return this.failTimeout();
7850				}
7851
7852				var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;
7853				var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
7854
7855				this.pTime = input.timeStamp;
7856				this.pCenter = input.center;
7857
7858				if (!validMultiTap || !validInterval) {
7859					this.count = 1;
7860				} else {
7861					this.count += 1;
7862				}
7863
7864				this._input = input;
7865
7866				// if tap count matches we have recognized it,
7867				// else it has began recognizing...
7868				var tapCount = this.count % options.taps;
7869				if (tapCount === 0) {
7870					// no failing requirements, immediately trigger the tap event
7871					// or wait as long as the multitap interval to trigger
7872					if (!this.hasRequireFailures()) {
7873						return STATE_RECOGNIZED;
7874					} else {
7875						this._timer = setTimeoutContext(function() {
7876							this.state = STATE_RECOGNIZED;
7877							this.tryEmit();
7878						}, options.interval, this);
7879						return STATE_BEGAN;
7880					}
7881				}
7882			}
7883			return STATE_FAILED;
7884		},
7885
7886		failTimeout: function() {
7887			this._timer = setTimeoutContext(function() {
7888				this.state = STATE_FAILED;
7889			}, this.options.interval, this);
7890			return STATE_FAILED;
7891		},
7892
7893		reset: function() {
7894			clearTimeout(this._timer);
7895		},
7896
7897		emit: function() {
7898			if (this.state == STATE_RECOGNIZED) {
7899				this._input.tapCount = this.count;
7900				this.manager.emit(this.options.event, this._input);
7901			}
7902		}
7903	});
7904
7905	/**
7906	 * Simple way to create a manager with a default set of recognizers.
7907	 * @param {HTMLElement} element
7908	 * @param {Object} [options]
7909	 * @constructor
7910	 */
7911	function Hammer(element, options) {
7912		options = options || {};
7913		options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
7914		return new Manager(element, options);
7915	}
7916
7917	/**
7918	 * @const {string}
7919	 */
7920	Hammer.VERSION = '2.0.8';
7921
7922	/**
7923	 * default settings
7924	 * @namespace
7925	 */
7926	Hammer.defaults = {
7927		/**
7928		 * set if DOM events are being triggered.
7929		 * But this is slower and unused by simple implementations, so disabled by default.
7930		 * @type {Boolean}
7931		 * @default false
7932		 */
7933		domEvents: false,
7934
7935		/**
7936		 * The value for the touchAction property/fallback.
7937		 * When set to `compute` it will magically set the correct value based on the added recognizers.
7938		 * @type {String}
7939		 * @default compute
7940		 */
7941		touchAction: TOUCH_ACTION_COMPUTE,
7942
7943		/**
7944		 * @type {Boolean}
7945		 * @default true
7946		 */
7947		enable: true,
7948
7949		/**
7950		 * EXPERIMENTAL FEATURE -- can be removed/changed
7951		 * Change the parent input target element.
7952		 * If Null, then it is being set the to main element.
7953		 * @type {Null|EventTarget}
7954		 * @default null
7955		 */
7956		inputTarget: null,
7957
7958		/**
7959		 * force an input class
7960		 * @type {Null|Function}
7961		 * @default null
7962		 */
7963		inputClass: null,
7964
7965		/**
7966		 * Default recognizer setup when calling `Hammer()`
7967		 * When creating a new Manager these will be skipped.
7968		 * @type {Array}
7969		 */
7970		preset: [
7971			// RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
7972			[RotateRecognizer, {enable: false}],
7973			[PinchRecognizer, {enable: false}, ['rotate']],
7974			[SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}],
7975			[PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']],
7976			[TapRecognizer],
7977			[TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']],
7978			[PressRecognizer]
7979		],
7980
7981		/**
7982		 * Some CSS properties can be used to improve the working of Hammer.
7983		 * Add them to this method and they will be set when creating a new Manager.
7984		 * @namespace
7985		 */
7986		cssProps: {
7987			/**
7988			 * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
7989			 * @type {String}
7990			 * @default 'none'
7991			 */
7992			userSelect: 'none',
7993
7994			/**
7995			 * Disable the Windows Phone grippers when pressing an element.
7996			 * @type {String}
7997			 * @default 'none'
7998			 */
7999			touchSelect: 'none',
8000
8001			/**
8002			 * Disables the default callout shown when you touch and hold a touch target.
8003			 * On iOS, when you touch and hold a touch target such as a link, Safari displays
8004			 * a callout containing information about the link. This property allows you to disable that callout.
8005			 * @type {String}
8006			 * @default 'none'
8007			 */
8008			touchCallout: 'none',
8009
8010			/**
8011			 * Specifies whether zooming is enabled. Used by IE10>
8012			 * @type {String}
8013			 * @default 'none'
8014			 */
8015			contentZooming: 'none',
8016
8017			/**
8018			 * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
8019			 * @type {String}
8020			 * @default 'none'
8021			 */
8022			userDrag: 'none',
8023
8024			/**
8025			 * Overrides the highlight color shown when the user taps a link or a JavaScript
8026			 * clickable element in iOS. This property obeys the alpha value, if specified.
8027			 * @type {String}
8028			 * @default 'rgba(0,0,0,0)'
8029			 */
8030			tapHighlightColor: 'rgba(0,0,0,0)'
8031		}
8032	};
8033
8034	var STOP = 1;
8035	var FORCED_STOP = 2;
8036
8037	/**
8038	 * Manager
8039	 * @param {HTMLElement} element
8040	 * @param {Object} [options]
8041	 * @constructor
8042	 */
8043	function Manager(element, options) {
8044		this.options = assign({}, Hammer.defaults, options || {});
8045
8046		this.options.inputTarget = this.options.inputTarget || element;
8047
8048		this.handlers = {};
8049		this.session = {};
8050		this.recognizers = [];
8051		this.oldCssProps = {};
8052
8053		this.element = element;
8054		this.input = createInputInstance(this);
8055		this.touchAction = new TouchAction(this, this.options.touchAction);
8056
8057		toggleCssProps(this, true);
8058
8059		each(this.options.recognizers, function(item) {
8060			var recognizer = this.add(new (item[0])(item[1]));
8061			item[2] && recognizer.recognizeWith(item[2]);
8062			item[3] && recognizer.requireFailure(item[3]);
8063		}, this);
8064	}
8065
8066	Manager.prototype = {
8067		/**
8068		 * set options
8069		 * @param {Object} options
8070		 * @returns {Manager}
8071		 */
8072		set: function(options) {
8073			assign(this.options, options);
8074
8075			// Options that need a little more setup
8076			if (options.touchAction) {
8077				this.touchAction.update();
8078			}
8079			if (options.inputTarget) {
8080				// Clean up existing event listeners and reinitialize
8081				this.input.destroy();
8082				this.input.target = options.inputTarget;
8083				this.input.init();
8084			}
8085			return this;
8086		},
8087
8088		/**
8089		 * stop recognizing for this session.
8090		 * This session will be discarded, when a new [input]start event is fired.
8091		 * When forced, the recognizer cycle is stopped immediately.
8092		 * @param {Boolean} [force]
8093		 */
8094		stop: function(force) {
8095			this.session.stopped = force ? FORCED_STOP : STOP;
8096		},
8097
8098		/**
8099		 * run the recognizers!
8100		 * called by the inputHandler function on every movement of the pointers (touches)
8101		 * it walks through all the recognizers and tries to detect the gesture that is being made
8102		 * @param {Object} inputData
8103		 */
8104		recognize: function(inputData) {
8105			var session = this.session;
8106			if (session.stopped) {
8107				return;
8108			}
8109
8110			// run the touch-action polyfill
8111			this.touchAction.preventDefaults(inputData);
8112
8113			var recognizer;
8114			var recognizers = this.recognizers;
8115
8116			// this holds the recognizer that is being recognized.
8117			// so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
8118			// if no recognizer is detecting a thing, it is set to `null`
8119			var curRecognizer = session.curRecognizer;
8120
8121			// reset when the last recognizer is recognized
8122			// or when we're in a new session
8123			if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {
8124				curRecognizer = session.curRecognizer = null;
8125			}
8126
8127			var i = 0;
8128			while (i < recognizers.length) {
8129				recognizer = recognizers[i];
8130
8131				// find out if we are allowed try to recognize the input for this one.
8132				// 1.   allow if the session is NOT forced stopped (see the .stop() method)
8133				// 2.   allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
8134				//      that is being recognized.
8135				// 3.   allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
8136				//      this can be setup with the `recognizeWith()` method on the recognizer.
8137				if (session.stopped !== FORCED_STOP && ( // 1
8138					!curRecognizer || recognizer == curRecognizer || // 2
8139					recognizer.canRecognizeWith(curRecognizer))) { // 3
8140					recognizer.recognize(inputData);
8141				} else {
8142					recognizer.reset();
8143				}
8144
8145				// if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
8146				// current active recognizer. but only if we don't already have an active recognizer
8147				if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
8148					curRecognizer = session.curRecognizer = recognizer;
8149				}
8150				i++;
8151			}
8152		},
8153
8154		/**
8155		 * get a recognizer by its event name.
8156		 * @param {Recognizer|String} recognizer
8157		 * @returns {Recognizer|Null}
8158		 */
8159		get: function(recognizer) {
8160			if (recognizer instanceof Recognizer) {
8161				return recognizer;
8162			}
8163
8164			var recognizers = this.recognizers;
8165			for (var i = 0; i < recognizers.length; i++) {
8166				if (recognizers[i].options.event == recognizer) {
8167					return recognizers[i];
8168				}
8169			}
8170			return null;
8171		},
8172
8173		/**
8174		 * add a recognizer to the manager
8175		 * existing recognizers with the same event name will be removed
8176		 * @param {Recognizer} recognizer
8177		 * @returns {Recognizer|Manager}
8178		 */
8179		add: function(recognizer) {
8180			if (invokeArrayArg(recognizer, 'add', this)) {
8181				return this;
8182			}
8183
8184			// remove existing
8185			var existing = this.get(recognizer.options.event);
8186			if (existing) {
8187				this.remove(existing);
8188			}
8189
8190			this.recognizers.push(recognizer);
8191			recognizer.manager = this;
8192
8193			this.touchAction.update();
8194			return recognizer;
8195		},
8196
8197		/**
8198		 * remove a recognizer by name or instance
8199		 * @param {Recognizer|String} recognizer
8200		 * @returns {Manager}
8201		 */
8202		remove: function(recognizer) {
8203			if (invokeArrayArg(recognizer, 'remove', this)) {
8204				return this;
8205			}
8206
8207			recognizer = this.get(recognizer);
8208
8209			// let's make sure this recognizer exists
8210			if (recognizer) {
8211				var recognizers = this.recognizers;
8212				var index = inArray(recognizers, recognizer);
8213
8214				if (index !== -1) {
8215					recognizers.splice(index, 1);
8216					this.touchAction.update();
8217				}
8218			}
8219
8220			return this;
8221		},
8222
8223		/**
8224		 * bind event
8225		 * @param {String} events
8226		 * @param {Function} handler
8227		 * @returns {EventEmitter} this
8228		 */
8229		on: function(events, handler) {
8230			if (events === undefined) {
8231				return;
8232			}
8233			if (handler === undefined) {
8234				return;
8235			}
8236
8237			var handlers = this.handlers;
8238			each(splitStr(events), function(event) {
8239				handlers[event] = handlers[event] || [];
8240				handlers[event].push(handler);
8241			});
8242			return this;
8243		},
8244
8245		/**
8246		 * unbind event, leave emit blank to remove all handlers
8247		 * @param {String} events
8248		 * @param {Function} [handler]
8249		 * @returns {EventEmitter} this
8250		 */
8251		off: function(events, handler) {
8252			if (events === undefined) {
8253				return;
8254			}
8255
8256			var handlers = this.handlers;
8257			each(splitStr(events), function(event) {
8258				if (!handler) {
8259					delete handlers[event];
8260				} else {
8261					handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
8262				}
8263			});
8264			return this;
8265		},
8266
8267		/**
8268		 * emit event to the listeners
8269		 * @param {String} event
8270		 * @param {Object} data
8271		 */
8272		emit: function(event, data) {
8273			// we also want to trigger dom events
8274			if (this.options.domEvents) {
8275				triggerDomEvent(event, data);
8276			}
8277
8278			// no handlers, so skip it all
8279			var handlers = this.handlers[event] && this.handlers[event].slice();
8280			if (!handlers || !handlers.length) {
8281				return;
8282			}
8283
8284			data.type = event;
8285			data.preventDefault = function() {
8286				data.srcEvent.preventDefault();
8287			};
8288
8289			var i = 0;
8290			while (i < handlers.length) {
8291				handlers[i](data);
8292				i++;
8293			}
8294		},
8295
8296		/**
8297		 * destroy the manager and unbinds all events
8298		 * it doesn't unbind dom events, that is the user own responsibility
8299		 */
8300		destroy: function() {
8301			this.element && toggleCssProps(this, false);
8302
8303			this.handlers = {};
8304			this.session = {};
8305			this.input.destroy();
8306			this.element = null;
8307		}
8308	};
8309
8310	/**
8311	 * add/remove the css properties as defined in manager.options.cssProps
8312	 * @param {Manager} manager
8313	 * @param {Boolean} add
8314	 */
8315	function toggleCssProps(manager, add) {
8316		var element = manager.element;
8317		if (!element.style) {
8318			return;
8319		}
8320		var prop;
8321		each(manager.options.cssProps, function(value, name) {
8322			prop = prefixed(element.style, name);
8323			if (add) {
8324				manager.oldCssProps[prop] = element.style[prop];
8325				element.style[prop] = value;
8326			} else {
8327				element.style[prop] = manager.oldCssProps[prop] || '';
8328			}
8329		});
8330		if (!add) {
8331			manager.oldCssProps = {};
8332		}
8333	}
8334
8335	/**
8336	 * trigger dom event
8337	 * @param {String} event
8338	 * @param {Object} data
8339	 */
8340	function triggerDomEvent(event, data) {
8341		var gestureEvent = document.createEvent('Event');
8342		gestureEvent.initEvent(event, true, true);
8343		gestureEvent.gesture = data;
8344		data.target.dispatchEvent(gestureEvent);
8345	}
8346
8347	assign(Hammer, {
8348		INPUT_START: INPUT_START,
8349		INPUT_MOVE: INPUT_MOVE,
8350		INPUT_END: INPUT_END,
8351		INPUT_CANCEL: INPUT_CANCEL,
8352
8353		STATE_POSSIBLE: STATE_POSSIBLE,
8354		STATE_BEGAN: STATE_BEGAN,
8355		STATE_CHANGED: STATE_CHANGED,
8356		STATE_ENDED: STATE_ENDED,
8357		STATE_RECOGNIZED: STATE_RECOGNIZED,
8358		STATE_CANCELLED: STATE_CANCELLED,
8359		STATE_FAILED: STATE_FAILED,
8360
8361		DIRECTION_NONE: DIRECTION_NONE,
8362		DIRECTION_LEFT: DIRECTION_LEFT,
8363		DIRECTION_RIGHT: DIRECTION_RIGHT,
8364		DIRECTION_UP: DIRECTION_UP,
8365		DIRECTION_DOWN: DIRECTION_DOWN,
8366		DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
8367		DIRECTION_VERTICAL: DIRECTION_VERTICAL,
8368		DIRECTION_ALL: DIRECTION_ALL,
8369
8370		Manager: Manager,
8371		Input: Input,
8372		TouchAction: TouchAction,
8373
8374		TouchInput: TouchInput,
8375		MouseInput: MouseInput,
8376		PointerEventInput: PointerEventInput,
8377		TouchMouseInput: TouchMouseInput,
8378		SingleTouchInput: SingleTouchInput,
8379
8380		Recognizer: Recognizer,
8381		AttrRecognizer: AttrRecognizer,
8382		Tap: TapRecognizer,
8383		Pan: PanRecognizer,
8384		Swipe: SwipeRecognizer,
8385		Pinch: PinchRecognizer,
8386		Rotate: RotateRecognizer,
8387		Press: PressRecognizer,
8388
8389		on: addEventListeners,
8390		off: removeEventListeners,
8391		each: each,
8392		merge: merge,
8393		extend: extend,
8394		assign: assign,
8395		inherit: inherit,
8396		bindFn: bindFn,
8397		prefixed: prefixed
8398	});
8399
8400// this prevents errors when Hammer is loaded in the presence of an AMD
8401//  style loader but by script tag, not by the loader.
8402	var freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line
8403	freeGlobal.Hammer = Hammer;
8404
8405	if (typeof define === 'function' && define.amd) {
8406		define(function() {
8407			return Hammer;
8408		});
8409	} else if (typeof module != 'undefined' && module.exports) {
8410		module.exports = Hammer;
8411	} else {
8412		window[exportName] = Hammer;
8413	}
8414
8415})(window, document, 'Hammer');
8416"use strict";
8417
8418var ria_layout_manager = {
8419	init: function(){
8420		var _this = this;
8421
8422		// console.log('ria_layout_manager >>> inited');
8423
8424		_this.minHeightViewWidgets = 100;       // минимальная высота виджетов, если меньше то скрываются
8425		_this.headerToSmall = 0;              // размер прокрутки до маленького хедера
8426		_this.widgetsSize = false;              // высота области виджетов
8427		_this.stickedOn = ( $("#body").data('header-sticked-on') && $('#header').length > 0 ) ? true : false;   // флаг что на станице включен прилипающий хедер
8428
8429		_this.isMobile = ( typeof ria === 'object' && ria.mobileBrowser ) ? ria.mobileBrowser() : false;    // флаг что мобильный браузер
8430		_this.notPullToReload = 'page-nopulltoreload';                                  // класс на <html/> для запрета Push to reload
8431		/**  активность состояний */
8432		_this._state = {
8433			lenta : false,
8434			chat : false,
8435			live : false,
8436			project : false,
8437			notPull : false
8438		};
8439		/**  модификаторы вешаются на body */
8440		_this.mod = {
8441			hSticked :'m-header-sticked',
8442			hSmall : 'm-header-small',
8443			hBrand : 'm-header-brand',
8444			lenta : 'm-widget-lenta',
8445			chat : 'm-widget-chat',
8446			live : 'm-widget-live',
8447			project : 'm-widget-project'
8448		};
8449		/**  классы для идентификации кнопок управления виджетами */
8450		_this.button = {
8451			lenta : 'js__toggle-lenta',
8452			lentaMini: 'lenta__close',
8453			chat : 'js__toggle-chat',
8454			live : 'js__toggle-live',
8455			project : 'js__toggle-project',
8456			all: 'js__widgets-close'
8457		};
8458
8459		/** подключение history бля обработки открытия Ленты */
8460		if ( !!( window.history && history.pushState && history.replaceState ) ) {
8461			_this.historyHandlers();
8462		}
8463
8464		$(window).on( 'scroll resize', function () {
8465			if ( $('#header').hasClass('sticky') ) _this.headerStatesSwitching();
8466			_this.setWidgetsSize();
8467		});
8468
8469		_this.widgetsManager();
8470
8471		$( window ).scroll();
8472
8473		if ( ( '#header' ).length > 0 ) $( "#body" ).addClass( "m-header-ready" );
8474
8475	},
8476
8477	historyHandlers : function(){
8478		var _this = this;
8479		_this.fromHistory = false;
8480		_this.disablePopstate = false;
8481		/** Подписка на тригер изменеия состояния виджетов */
8482		$( 'body' ).bind( 'widget', function( e, n, s ){
8483			if ( n === 'lenta' && !_this.fromHistory ){
8484				if ( s === true ){
8485					history.pushState( { 'lenta' : true }, null, location.href )
8486				} else {
8487					_this.disablePopstate = true;
8488					history.back()
8489				}
8490			}
8491
8492            if ( n == 'chat' && !_this.fromHistory ){
8493                if ( s == true ){
8494                    history.pushState( { 'chat' : true }, null, location.href )
8495                } else {
8496                    _this.disablePopstate = true;
8497                    history.back()
8498                }
8499            }
8500
8501			_this.fromHistory = false;
8502		} );
8503		window.addEventListener( "popstate", function( e ) {
8504			if ( !_this.disablePopstate ){
8505				_this.fromHistory = true;
8506				if ( e.state && e.state.lenta && e.state.lenta === true ) {
8507					_this.changeState( 'lenta', true );
8508				} else {
8509					_this.changeState( 'lenta', false );
8510				}
8511
8512                if ( e.state && e.state.chat && e.state.chat === true ) {
8513                    _this.changeState( 'chat', true );
8514                } else {
8515                    _this.changeState( 'chat', false );
8516                    dataLayer.push({ 'block' : 'chat_widget', 'event' : 'chat_close_back' });
8517                }
8518			}
8519			_this.disablePopstate = false;
8520		}, false );
8521	},
8522
8523	/** управление прилипанием хедера */
8524	headerStatesSwitching : function(){
8525		var _this = this,
8526			$b = $( '#body' ),
8527			limit = $( '#header' ).offset().top + ( $b.hasClass( _this.mod.hBrand ) ? $( '#header' ).outerHeight() : 0 ) ;
8528		this.headerStatesCheck( limit, $b.hasClass( _this.mod.hSticked ), _this.mod.hSticked);
8529		this.headerStatesCheck( limit + _this.headerToSmall, $b.hasClass( _this.mod.hSmall ), _this.mod.hSmall);
8530	},
8531	
8532	headerStatesCheck : function( limit, flag, cl ){
8533		var st = $( window ).scrollTop();
8534		if ( st >= limit && !flag ) {
8535			$( '#body' ).addClass( cl );
8536		} else if ( st == 0 || ( st < limit && flag ) ){
8537			$( '#body' ).removeClass( cl );
8538		}
8539	},
8540
8541	/** выставление высоты зоны с виджетами */
8542	setWidgetsSize: function(){
8543		var _this = this,
8544			widgetsHeight = '100%',
8545			$headerHeight = $( '#header' );
8546	
8547		if ( this.getClientWidth() > 768 && $( window ).scrollTop() < $headerHeight.offset().top ) {
8548			widgetsHeight = _this.getViewHeight() - $headerHeight[ 0 ].getBoundingClientRect().top;
8549		}
8550		if ( _this.widgetsSize != widgetsHeight ) {
8551			if ( widgetsHeight < _this.minHeightViewWidgets ) widgetsHeight = 0;
8552			$( '#widgetsSize' ).height( widgetsHeight );
8553			_this.widgetsSize = widgetsHeight;
8554		}
8555	},
8556
8557	widgetsManager: function(){
8558		var _this = this,
8559			$body = $( 'body' ),
8560			_s = _this._state;
8561
8562		$( window ).on( 'resize', function () {
8563			var clientWidth = _this.getClientWidth();
8564			/** закрываем виджеты чата или лайв трансляции, если открыта лента */
8565			if ( _s.lenta && clientWidth < 768 && ( _s.chat || _s.live || _s.project ) ) {
8566				_this.changeState({
8567					'chat': false,
8568					'live': false,
8569					'project': false
8570				});
8571			}
8572			if ( ( _s.lenta || _s.live || _s.chat || _s.project ) && !$('#modalLayer').hasClass('m-open') ) {
8573				ria.disablePageScroll( clientWidth >= 768 ? false : true );
8574			}
8575		});
8576
8577		/** click по body закрывает ленту при разрешении более 768 */
8578		// $body.on( 'click', function(){
8579		// 	if ( _this.getClientWidth() >= 768 &&  (_this._state.lenta ||  _this._state.project) ) {
8580		// 		_this.changeState( {'lenta': false, 'project': false } );
8581		// 	}
8582		// });
8583		$body.on( 'click', function(){
8584			if ( (_this._state.lenta ||  _this._state.project) ) {
8585				_this.changeState( {'lenta': false, 'project': false } );
8586			}
8587		});
8588
8589		$( '.project__place' ).on( 'click', function( e ){
8590			if ( _this._state.project ) {
8591				e.stopPropagation();
8592			};
8593		});
8594
8595		$( '#widgetBottom' ).on( 'click', function( e ){
8596			if ( _this._state.lenta ) {
8597				e.stopPropagation();
8598			};
8599		});
8600
8601		$( '.'+_this.button.live ).on( 'click', function(e){
8602			e.stopPropagation();
8603			e.preventDefault();
8604			if ( _this._state.live ) {
8605				_this._state.lenta ? _this.changeState( 'lenta', false ) : _this.changeState( 'live', false );
8606			} else {
8607				_this.changeState({
8608					'lenta': false,
8609					'chat': false,
8610					'project': false,
8611					'live': true
8612				});
8613			}
8614		});
8615
8616		$( '.'+_this.button.chat ).on( 'click', function( e ){
8617			e.stopPropagation();
8618			e.preventDefault();
8619			if ( _this._state.chat ) {
8620				_this._state.lenta ? _this.changeState( 'lenta', false ) : _this.changeState( 'chat', false );
8621			} else {
8622				_this.changeState({
8623					'lenta': false,
8624					'chat': true,
8625					'project': false,
8626					'live': false
8627				});
8628			}
8629		});
8630
8631		$( '.'+_this.button.lenta ).on( 'click', function( e ){
8632			e.stopPropagation();
8633			e.preventDefault();
8634			_this._state.lenta ? _this.changeState( 'lenta', false ) : _this.changeState( 'lenta', true );
8635		});
8636
8637		$( '.'+_this.button.lentaMini ).on( 'click', function( e ){
8638			e.stopPropagation();
8639			e.preventDefault();
8640			if(_this._state.lenta) {
8641				_this.changeState('lenta', false);
8642			}
8643		});
8644
8645		$( '.'+_this.button.project ).on( 'click', function( e ){
8646			e.stopPropagation();
8647			e.preventDefault();
8648			if ( _this._state.project ) {
8649				_this._state.lenta ? _this.changeState( 'lenta', false ) : _this.changeState( 'project', false );
8650			} else {
8651				_this.changeState({
8652					'lenta': false,
8653					'chat': false,
8654					'project': true,
8655					'live': false
8656				});
8657			}
8658		});
8659
8660		$('body').on( 'click', '.' +_this.button.all, function( e ){
8661			e.stopPropagation();
8662			e.preventDefault();
8663			_this.changeState({
8664				'lenta': false,
8665				'chat': false,
8666				'live': false,
8667				'project': false
8668			});
8669		});
8670
8671	},
8672
8673	/** Отключение pull to reload посредством html { overflow:hidden } при открытии чата
8674	 * #RIA2018-755
8675	 * стало не нужным всвязи с обновой Хрома - оставили прозапас */
8676	disablePullToReload: function( allow ){
8677		if ( this.isMobile && ( allow === true || this._state.lenta || this._state.chat || this._state.live ) && this.getClientWidth() < 768 ){
8678			$( 'html' ).addClass( this.notPullToReload );
8679			this._state.notPull = true;
8680		} else if ( allow === false || ( !this._state.lenta || !this._state.chat || !this._state.live ) ){
8681			$( 'html' ).removeClass( this.notPullToReload );
8682			this._state.notPull = false;
8683		}
8684	},
8685
8686	changeState: function( n, s ) {
8687		var _this = this;
8688		if ( $.isPlainObject( n ) || ( typeof n == "string" && typeof s == "boolean" )  ) {
8689			var is_state = false,
8690				obj = {};
8691			if ( $.isPlainObject( n ) ) {
8692				obj = n;
8693			} else {
8694				obj[n] = s;
8695			}
8696			$.each( obj , function( k, v ){
8697				if ( _this._state[ k ] != v ) _this.setState( k, v );
8698				if ( v ) is_state = true;
8699				if ( k === 'lenta' ) ria.disablePageScroll( v );
8700			});
8701			if(typeof ria === 'object') {
8702				ria.dispatch('widget',obj);
8703			}
8704			if ( _this.getClientWidth() < 768 ) ria.disablePageScroll( is_state );
8705		} else {
8706			return false
8707		}
8708		/*TODO test */ //console.log(_this._state);
8709	},
8710
8711	setState: function( n, s ){
8712		var _this = this;
8713		if ( typeof n == "string" && typeof s == "boolean") {
8714			if ( s ) {
8715				_this._state[ n ] = true;
8716				$( 'body' ).addClass( _this.mod[ n ] );
8717			} else {
8718				_this._state[ n ] = false;
8719				$( 'body' ).removeClass( _this.mod[ n ] );
8720			}
8721			$( 'body' ).trigger( 'widget', [ n, s ] );
8722		} else {
8723			return false;
8724		}
8725	},
8726
8727	/**
8728	 * получение ширины контентной области клиента
8729	 * @returns {Number} size
8730	 */
8731	getViewWidth: function(){
8732		var $viewSize = $('#jsViewSize');
8733		return $viewSize.length > 0 ? parseInt($viewSize.width()) : this.getClientWidth();
8734	},
8735	/**
8736	 * получение высоты контентной области клиента
8737	 * @returns {Number} size
8738	 */
8739	getViewHeight: function(){
8740		var $viewSize = $('#jsViewSize');
8741		return $viewSize.length > 0 ? parseInt($viewSize.height()) : this.getClientHeigth();
8742	},
8743	/**
8744	 * получение ширины окна клиента
8745	 * @returns {Number} size
8746	 */
8747	getClientWidth: function(){
8748		return Math.max(window.innerWidth || 0, (document.getElementsByTagName('html')[0] || {}).clientWidth || 0)
8749	},
8750	/**
8751	 * получение высоты окна клиента
8752	 * @returns {Number} size
8753	 */
8754	getClientHeigth: function(){
8755		return  Math.max(window.innerHeight || 0, (document.getElementsByTagName('html')[0] || {}).clientHeight || 0)
8756	}
8757};
8758"use strict";
8759
8760
8761var ria_live_manager = {
8762
8763	init: function () {
8764		var _this = this;
8765		_this.$live = $('#widgetRLive');
8766
8767		if (_this.$live.length <= 0) return false;
8768
8769		// console.log('RIA - LIVE inited');
8770		// console.log(_this.$live);
8771
8772        _this.mod = {
8773            view_list : 'm-view-list',
8774            no_list : 'm-no-list'
8775        };
8776
8777        _this.$title = $('.widgets__r-header-one span', _this.$live);
8778        _this.$url = $('.widgets__r-header-one a', _this.$live);
8779        _this.$loader = $('.widgets__r-loader', _this.$live);
8780		_this.$list = $('.widgets__r-list', _this.$live);
8781		_this.$back = $('.widgets__r-header-button.m-back', _this.$live);
8782
8783		_this.checkActive();
8784		_this.addEvents();
8785
8786	},
8787
8788	addEvents : function(){
8789		var _this = this;
8790
8791		_this.$list.on('click', '.r-list__item', function(){
8792			_this.toOnline($(this));
8793		});
8794
8795		_this.$back.on('click', function(){
8796			_this.toList();
8797		})
8798	},
8799
8800	checkActive : function(){
8801		var _this = this;
8802        if (_this.$live.hasClass(_this.mod.view_list)){
8803            _this.toList();
8804        } else if (_this.$list.length <= 0){
8805			_this.$live.addClass(_this.mod.no_list);
8806		}
8807	},
8808
8809	toList: function () {
8810		var _this = this;
8811		_this.$live.addClass(_this.mod.view_list);
8812	},
8813
8814	toOnline: function (obj) {
8815		var _this = this;
8816        _this.setTitle(obj.data('title'));
8817        _this.setUrl(obj.data('url'));
8818        //_this.$loader.show();
8819		_this.$live.removeClass(_this.mod.view_list);
8820		if ( typeof obj == 'object' ){
8821			// проверка какой онлайн уже загружен
8822			// если нужен другой - AJAX запрос
8823			// показываем лоадер
8824			// заменяем контент
8825			// скрываем лоадер
8826		}
8827
8828	},
8829
8830	setTitle: function (text) {
8831		return (!this.$title) ? false : this.$title.html(text);
8832	},
8833	setUrl: function (text) {
8834		return (!this.$url) ? false : this.$url.attr('href', text);
8835	}
8836
8837
8838};
8839
8840$(function(){
8841    ria_live_manager.init();
8842});
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867$(function() {
8868	var lenta = {
8869		init: function({rtl}) {
8870			var _this = this;
8871			_this.$elem = $("#widgetLenta .lenta__content");
8872
8873			_this.cashList = false;
8874			_this.loading = false;
8875			_this.waitList = false;
8876			_this.title = $('.lenta__header');
8877			_this.body = $('#body');
8878			_this.maxdate = $('#widgetLenta').data('maxtime')*1000;
8879			_this.loader_delay = 3000;
8880			_this.delay = 700;
8881			_this.widget = $('.widgets__b-slide');
8882
8883			_this.$elem.theinScroll({
8884				rtl:rtl
8885			});
8886
8887			window.dataLayer = window.dataLayer || [];
8888
8889			$('body').on('widget', function(e, n, s) {
8890				if (n == 'lenta' && s) {
8891					if ( _this.$elem.find('.lenta__list').height() < _this.$elem.height() ) {
8892						if (_this.cashList) {
8893							_this.addList();
8894						} else if(_this.loading) {
8895							_this.waitList = true;
8896						} else {
8897							_this.updateCash();
8898						}
8899					}
8900					if ( $('#widgetLenta .lenta__alert').length ) {
8901						_this.$elem.css( 'top', $('#widgetLenta .lenta__alert').outerHeight() );
8902					}
8903					dataLayer.push({ 'block' : 'lenta_widget', 'event' : 'lenta_open' });
8904				}
8905				if (n == 'lenta' && !s) {
8906					_this.$elem.trigger('scroll-up.the-in-scroll', [ 0, 100]);
8907					_this.$elem.css( 'top', '' );
8908					dataLayer.push({ 'block' : 'lenta_widget', 'event' : 'lenta_close' });
8909				}
8910			});
8911
8912			function miniLenta() {
8913				_this.body.addClass('m-widget-lenta-mini');
8914				_this.body.removeClass('m-widget-lenta-active');
8915				$('.js__counter-lenta').addClass('m-zero').text(0);
8916				ria.lsSet('ria_lenta_mini', '0');
8917				dataLayer.push({ 'block' : 'lenta_widget', 'event' : 'lenta_hide' });
8918			}
8919
8920			$('.lenta__close').on('click', function() {
8921				miniLenta();
8922			});
8923
8924			$('.lenta-mini').on('click', function() {
8925				_this.body.removeClass('m-widget-lenta-mini');
8926				_this.body.addClass('m-widget-lenta-active');
8927				_this.widget.addClass('m-transitiondelay');
8928				_this.widget.on('transitionend', function() {
8929					$(this).removeClass('m-transitiondelay');
8930				});
8931				ria.lsRemove('ria_lenta_mini');
8932			});
8933
8934			if (typeof ria === 'object' && ria.lsGet('ria_lenta_mini')) {
8935				if ( parseInt( ria.lsGet('ria_lenta_mini') ) > 0 ) {
8936					$('.js__counter-lenta').removeClass('m-zero');
8937				}
8938				$('.js__counter-lenta').text( ria.lsGet('ria_lenta_mini') );
8939				_this.body.addClass('m-widget-lenta-mini');
8940			} else {
8941				_this.body.addClass('m-widget-lenta-active');
8942			}
8943
8944			if ( _this.getClientWidth() < 768 && 'ontouchstart' in document.documentElement ) {
8945				var list = _this.$elem.find('.lenta__list');
8946				var mc = new Hammer( $('.widgets__b-cover').get(0) );
8947				var lenta_pos_top = $('.widgets__b-slide').position().top;
8948				mc.get('pan').set({ direction: Hammer.DIRECTION_ALL });
8949
8950				$('#widgetLenta').css({
8951					'touch-action': 'none',
8952					'user-select': 'none',
8953					'-webkit-user-drag': 'none'
8954				});
8955
8956				mc.on('panstart', function(e) {
8957					list.addClass('m-lenta-pan');
8958					_this.widget.addClass('m-notransition');
8959					lenta_pos_top = _this.widget.position().top;
8960				});
8961
8962				mc.on('panmove', function(e) {
8963					_this.widget.css('top', e.deltaY + lenta_pos_top );
8964				});
8965
8966				mc.on('panend pancancel', function(e) {
8967					list.removeClass('m-lenta-pan');
8968					_this.widget.removeClass('m-notransition');
8969
8970					if ( _this.body.hasClass('m-widget-lenta') &&  e.deltaY > 100  ) {
8971						_this.widget.css('top', '' );
8972						ria_layout_manager.changeState( 'lenta', false );
8973					} else if ( !_this.body.hasClass('m-widget-lenta') && e.deltaY > 20 ) {
8974						_this.widget.css('top', '');
8975						miniLenta();
8976					} else if (e.deltaY < -100) {
8977						_this.widget.css('top', '');
8978						ria_layout_manager.changeState( 'lenta', true );
8979					} else {
8980						_this.widget.css('top', lenta_pos_top );
8981						_this.widget.on('transitionend', function() {
8982							$(this).css('top', '' );
8983						});
8984					}
8985				});
8986			}
8987
8988			$('#widgetLenta a').on('click', function() {
8989				dataLayer.push({ 'block' : 'lenta_widget', 'event' : 'lenta_link', 'link' : $(this).attr('href') });
8990			});
8991
8992			_this.$elem.trigger('add-scrolling-trigger.the-in-scroll', [ {
8993				name: 'lenta_loadmore',
8994				down: true,
8995				sign: '<',
8996				position: 75,
8997				move: true
8998			} ]);
8999
9000			_this.$elem.on('lenta_loadmore.the-in-scroll', function(e) {
9001				if ( _this.body.hasClass('m-widget-lenta') ) {
9002					if (_this.cashList) {
9003						_this.addList();
9004					} else if(_this.loading) {
9005						_this.waitList = true;
9006					} else {
9007						_this.updateCash();
9008					}
9009				}
9010			});
9011
9012			ria_sock && ria_sock.on('bus_notify', function(data) {
9013                var charset = GLOBAL.charset.toLowerCase();
9014
9015				if ( (data.subtype === 'new_article') && (data.lang === GLOBAL.lang) ) {
9016                    if (charset) {
9017                        if (charset === data.charset) {
9018                            _this.newArticle(data);
9019                        }
9020                    } else {
9021                        if (!data.charset) {
9022                            _this.newArticle(data);
9023                        }
9024                    }
9025				}
9026			});
9027
9028			if($('.lenta__item-date.convert-date').length){
9029				ria.convertDate('.lenta .lenta__item-date');
9030				setInterval(function () {
9031					if(typeof ria === 'object'){
9032						ria.convertDate('.lenta .lenta__item-date');
9033					}
9034				},1000 * 60);
9035			}
9036		},
9037		updateCash : function() {
9038			if (!this.cashList) {
9039				var _this = this,
9040					url = _this.$elem.find('.lenta__item:last').data('next');
9041				if (url) {
9042					_this.loading = true;
9043					$.ajax({
9044						url: url,
9045						dataType: 'html'
9046					}).done(function(response) {
9047						_this.cashList = response;
9048						_this.loading = false;
9049						if (_this.waitList) {
9050							_this.addList();
9051							_this.waitList = false;
9052						}
9053					}).fail(function() {
9054						_this.loading = false;
9055					});
9056				} else {
9057					_this.$elem.off('lenta_loadmore.the-in-scroll');
9058				}
9059			}
9060		},
9061		addList : function() {
9062			if (this.cashList) {
9063				var _this = this,
9064					$dataContainer = _this.$elem.data('theinScroll').$container;
9065				$dataContainer.find('.lenta__item:last').removeAttr('data-next');
9066				$dataContainer.find('.lenta__list').append(_this.cashList);
9067				_this.cashList = false;
9068				_this.updateCash();
9069				if(typeof ria === 'object'){
9070					ria.convertDate();
9071				}
9072			}
9073		},
9074		newArticle: function(message) {
9075			var _this = this;
9076
9077			var article_date = message.article_date,
9078				lenta_curdate = Date.now(),
9079				width = ria.getClientWidth();
9080
9081			article_date = article_date.split(' ');
9082			article_date = Date.parse( article_date[0] + 'T' + article_date[1] + article_date[2].substr(0, 3) + ':' + article_date[2].substr(3, 2) );
9083
9084			if (article_date > _this.maxdate && article_date < lenta_curdate) {
9085				_this.maxdate = article_date;
9086
9087				if ( _this.body.hasClass('m-widget-lenta-mini') || $('#widgetLenta').hasClass('lenta-alert') ) {
9088					_this.renderHidden(message);
9089				} else if (width > 1189 && !_this.body.hasClass('m-widget-lenta') ) {
9090					_this.renderColumnAnimate(message);
9091				} else if (_this.body.hasClass('m-widget-lenta')) {
9092					_this.renderListAnimate(message);
9093				} else {
9094					_this.renderLineAnimate(message);
9095				}
9096				_this.renderMini(message);
9097			}
9098
9099			if(typeof ria === 'object'){
9100				ria.convertDate();
9101			}
9102		},
9103		insertArticle:function(el, message){
9104			var url = message.article_url.lastIndexOf('http', 0) === 0 ? message.article_url : GLOBAL.www + message.article_url;
9105			var date = message.article_date.substring(0, 10) + 'T' + message.article_date.substring(11, 19) + message.article_date.substring(20, 25);
9106			var unixtime = new Date(date).getTime()/1000;
9107			var convertClass = $('.lenta__item-date.convert-date').length ? 'convert-date' : '';
9108
9109			// console.log(date);
9110			el.html('<a href="'+ url +'" class="lenta__item-size"><span class="lenta__item-decription"><span class="lenta__item-date '+ convertClass +'" data-unixtime="' + unixtime +'"><span class="date">'+ message.article_date.substr(11, 5) +'</span></span><span class="lenta__item-text ' + convertClass + '">'+ message.article_title +'</span></span></a>');
9111			if (message.article_priority == 1) {
9112				el.addClass('lenta__item-warn');
9113				el.find('.lenta__item-text').append('<span class="lenta__item-icon m-breaking"><svg class="svg-icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="'+ ria.getIcon('flash')+ '"></use></svg></span>');
9114			}
9115
9116			if(typeof ria === 'object'){
9117				ria.convertDate();
9118			}
9119		},
9120		renderColumnAnimate: function(message){
9121			var _this = this;
9122			var list = _this.$elem.find('.lenta__list');
9123			var el = $(document.createElement('div')).addClass('lenta__item');
9124
9125			_this.insertArticle(el, message);
9126
9127			_this.title.addClass('m-color');
9128			list.prepend(el).addClass('shift');
9129
9130			setTimeout(function() {
9131				list.addClass('animate');
9132			},100);
9133
9134			setTimeout(function() {
9135				list.removeClass('shift animate');
9136				el.addClass('m-color');
9137			},700);
9138
9139			setTimeout(function() {
9140				_this.title.removeClass('m-color');
9141				el.removeClass('m-color');
9142			},1400);
9143
9144		},
9145		renderLineAnimate: function(message){
9146			var _this = this;
9147			var el = $(document.createElement('div'));
9148			var firstEl = _this.$elem.find('.lenta__item').first();
9149
9150			_this.$elem.find('.lenta__list').prepend(el);
9151
9152			el.addClass('lenta__item empty show m-color');
9153
9154			setTimeout(function() {
9155				firstEl.addClass('hide');
9156				_this.title.addClass('m-color');
9157			},  _this.delay);
9158			setTimeout(function() {
9159				el.removeClass('empty');
9160			},  _this.delay + 100);
9161			setTimeout(function() {
9162				_this.insertArticle(el, message);
9163				el.removeClass('show');
9164				firstEl.addClass('no-transition').removeClass('hide');
9165			}, _this.delay + 200);
9166			setTimeout(function() {
9167				_this.title.removeClass('m-color');
9168				el.removeClass('m-color');
9169				firstEl.removeClass('no-transition');
9170			}, _this.delay + 900);
9171
9172		},
9173		renderListAnimate: function(message){
9174			var _this = this;
9175			var el = $(document.createElement('div'));
9176			_this.$elem.find('.lenta__list').prepend(el);
9177
9178			el.addClass('lenta__item loading empty');
9179			_this.$elem.addClass('m-loading');
9180
9181			setTimeout(function() {
9182				el.removeClass('empty');
9183			}, 100);
9184			setTimeout(function() {
9185				_this.insertArticle(el, message);
9186			}, _this.loader_delay);
9187			setTimeout(function() {
9188				el.removeClass('loading');
9189				_this.$elem.removeClass('m-loading');
9190			}, _this.loader_delay + 100);
9191		},
9192		renderMini: function(message) {
9193			$('.js__counter-lenta.m-zero').removeClass('m-zero');
9194
9195			if (message.article_priority == 1) {
9196				$('.js__counter-lenta').addClass('m-alert');
9197			}
9198
9199			var count = parseInt( $('.js__counter-lenta').text() );
9200			$('.js__counter-lenta').text( count >= 99 ? '99+' : ++count );
9201			if ( ria.lsGet('ria_lenta_mini') ) {
9202				ria.lsSet('ria_lenta_mini', count);
9203			}
9204		},
9205		renderHidden: function(message) {
9206			var _this = this;
9207			var el = $(document.createElement('div'));
9208
9209			el.addClass('lenta__item');
9210			_this.insertArticle(el, message);
9211			_this.$elem.find('.lenta__list').prepend(el);
9212		},
9213		getClientWidth: function () {
9214			return Math.max( window.innerWidth || 0, ( document.getElementsByTagName( 'html' )[ 0 ] || {} ).clientWidth || 0)
9215		}
9216	};
9217
9218	// if ($("#widgetLenta").length) {
9219	// 	lenta.init({
9220	// 		rtl:Boolean(GLOBAL.rtl)
9221	// 	});
9222	// }
9223	$.ajax({
9224		url: '/services/widget/lenta/',
9225		dataType: 'html',
9226		type: 'GET',
9227		success: function ( data ) {
9228			const $lenta = $(data);
9229
9230			$('#widgetBottom .widgets__b-slide').append($lenta);
9231
9232			if ($("#widgetLenta").length) {
9233				lenta.init({
9234					rtl:Boolean(GLOBAL.rtl)
9235				});
9236			}
9237
9238			if(typeof ria_layout_manager ===  'object') {
9239				ria_layout_manager.init();
9240			}
9241		}
9242	})
9243});
9244
9245!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,i;function c(){return e.apply(null,arguments)}function o(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function u(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function l(e){return void 0===e}function d(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function h(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function f(e,t){var n,s=[];for(n=0;n<e.length;++n)s.push(t(e[n],n));return s}function m(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function _(e,t){for(var n in t)m(t,n)&&(e[n]=t[n]);return m(t,"toString")&&(e.toString=t.toString),m(t,"valueOf")&&(e.valueOf=t.valueOf),e}function y(e,t,n,s){return Ot(e,t,n,s,!0).utc()}function g(e){return null==e._pf&&(e._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invali
vendor: 6,580 bytes, line 9245
9245dFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}),e._pf}function p(e){if(null==e._isValid){var t=g(e),n=i.call(t.parsedDateParts,function(e){return null!=e}),s=!isNaN(e._d.getTime())&&t.overflow<0&&!t.empty&&!t.invalidMonth&&!t.invalidWeekday&&!t.weekdayMismatch&&!t.nullInput&&!t.invalidFormat&&!t.userInvalidated&&(!t.meridiem||t.meridiem&&n);if(e._strict&&(s=s&&0===t.charsLeftOver&&0===t.unusedTokens.length&&void 0===t.bigHour),null!=Object.isFrozen&&Object.isFrozen(e))return s;e._isValid=s}return e._isValid}function v(e){var t=y(NaN);return null!=e?_(g(t),e):g(t).userInvalidated=!0,t}i=Array.prototype.some?Array.prototype.some:function(e){for(var t=Object(this),n=t.length>>>0,s=0;s<n;s++)if(s in t&&e.call(this,t[s],s,t))return!0;return!1};var r=c.momentProperties=[];function w(e,t){var n,s,i;if(l(t._isAMomentObject)||(e._isAMomentObject=t._isAMomentObject),l(t._i)||(e._i=t._i),l(t._f)||(e._f=t._f),l(t._l)||(e._l=t._l),l(t._strict)||(e._strict=t._strict),l(t._tzm)||(e._tzm=t._tzm),l(t._isUTC)||(e._isUTC=t._isUTC),l(t._offset)||(e._offset=t._offset),l(t._pf)||(e._pf=g(t)),l(t._locale)||(e._locale=t._locale),0<r.length)for(n=0;n<r.length;n++)l(i=t[s=r[n]])||(e[s]=i);return e}var t=!1;function M(e){w(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===t&&(t=!0,c.updateOffset(this),t=!1)}function S(e){return e instanceof M||null!=e&&null!=e._isAMomentObject}function D(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function k(e){var t=+e,n=0;return 0!==t&&isFinite(t)&&(n=D(t)),n}function a(e,t,n){var s,i=Math.min(e.length,t.length),r=Math.abs(e.length-t.length),a=0;for(s=0;s<i;s++)(n&&e[s]!==t[s]||!n&&k(e[s])!==k(t[s]))&&a++;return a+r}function Y(e){!1===c.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function n(i,r){var a=!0;return _(function(){if(null!=c.deprecationHandler&&c.deprecationHandler(null,i),a){for(var e,t=[],n=0;n<arguments.length;n++){if(e="","object"==typeof arguments[n]){for(var s in e+="\n["+n+"] ",arguments[0])e+=s+": "+arguments[0][s]+", ";e=e.slice(0,-2)}else e=arguments[n];t.push(e)}Y(i+"\nArguments: "+Array.prototype.slice.call(t).join("")+"\n"+(new Error).stack),a=!1}return r.apply(this,arguments)},r)}var s,O={};function T(e,t){null!=c.deprecationHandler&&c.deprecationHandler(e,t),O[e]||(Y(t),O[e]=!0)}function x(e){return e instanceof Function||"[object Function]"===Object.prototype.toString.call(e)}function b(e,t){var n,s=_({},e);for(n in t)m(t,n)&&(u(e[n])&&u(t[n])?(s[n]={},_(s[n],e[n]),_(s[n],t[n])):null!=t[n]?s[n]=t[n]:delete s[n]);for(n in e)m(e,n)&&!m(t,n)&&u(e[n])&&(s[n]=_({},s[n]));return s}function P(e){null!=e&&this.set(e)}c.suppressDeprecationWarnings=!1,c.deprecationHandler=null,s=Object.keys?Object.keys:function(e){var t,n=[];for(t in e)m(e,t)&&n.push(t);return n};var W={};function H(e,t){var n=e.toLowerCase();W[n]=W[n+"s"]=W[t]=e}function R(e){return"string"==typeof e?W[e]||W[e.toLowerCase()]:void 0}function C(e){var t,n,s={};for(n in e)m(e,n)&&(t=R(n))&&(s[t]=e[n]);return s}var F={};function L(e,t){F[e]=t}function U(e,t,n){var s=""+Math.abs(e),i=t-s.length;return(0<=e?n?"+":"":"-")+Math.pow(10,Math.max(0,i)).toString().substr(1)+s}var N=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,G=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,V={},E={};function I(e,t,n,s){var i=s;"string"==typeof s&&(i=function(){return this[s]()}),e&&(E[e]=i),t&&(E[t[0]]=function(){return U(i.apply(this,arguments),t[1],t[2])}),n&&(E[n]=function(){return this.localeData().ordinal(i.apply(this,arguments),e)})}function A(e,t){return e.isValid()?(t=j(t,e.localeData()),V[t]=V[t]||function(s){var e,i,t,r=s.match(N);for(e=0,i=r.length;e<i;e++)E[r[e]]?r[e]=E[r[e]]:r[e]=(t=r[e]).match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"");return function(e){var t,n="";for(t=0;t<i;t++)n+=x(r[t])?r[t].call(e,s):r[t];return n}}(t),V[t](e)):e.localeData().invalidDate()}function j(e,t){var n=5;function s(e){return t.longDateFormat(e)||e}for(G.lastIndex=0;0<=n&&G.test(e);)e=e.replace(G,s),G.lastIndex=0,n-=1;return e}var Z=/\d/,z=/\d\d/,$=/\d{3}/,q=/\d{4}/,J=/[+-]?\d{6}/,B=/\d\d?/,Q=/\d\d\d\d?/,X=/\d\d\d\d\d\d?/,K=/\d{1,3}/,ee=/\d{1,4}/,te=/[+-]?\d{1,6}/,ne=/\d+/,se=/[+-]?\d+/,ie=/Z|[+-]\d\d:?\d\d/gi,re=/Z|[+-]\d\d(?::?\d\d)?/gi,ae=/[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,oe={};function ue(e,n,s){oe[e]=x(n)?n:function(e,t){return e&&s?s:n}}function le(e,t){return m(oe,e)?oe[e](t._strict,t._locale):new RegExp(de(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(e,t,n,s,i){return t||n||s||i})))}function de(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var he={};function ce(e,n){var t,s=n;for("string"==typeof e&&(e=[e]),d(n)&&(s=function(e,t){t[n]=k(e)}),t=0;t<e.length;t++)he[e[t]]=s}function fe(e,i){ce(e,function(e,t,n,s){n._w=n._w||{},i(e,n._w,n,s)})}var me=0,_e=1,ye=2,ge=3,pe=4,ve=5,we=6,Me=7,Se=8;function De(e){return ke(e)?366:365}function ke(e){return e%4==0&&e%100!=0||e%400==0}I("Y",0,0,function(){var e=this.year();return e<=9999?""+e:"+"+e}),I(0,["YY",2],0,function(){return this.year()%100}),I(0,["YYYY",4],0,"year"),I(0,["YYYYY",5],0,"year"),I(0,["YYYYYY",6,!0],0,"year"),H("year","y"),L("year",1),ue("Y",se),ue("YY",B,z),ue("YYYY",ee,q),ue("YYYYY",te,J),ue("YYYYYY",te,J),ce(["YYYYY","YYYYYY"],me),ce("YYYY",function(e,t){t[me]=2===e.length?c.parseTwoDigitYear(e):k(e)}),ce("YY",function(e,t){t[me]=c.parseTwoDigitYear(e)}),ce("Y",function(e,t){t[me]=parseInt(e,10)}),c.parseTwoDigitYear=function(e){return k(e)+(68<k(e)?1900:2e3)};var Ye,Oe=Te("FullYear",!0);function Te(t,n){return function(e){return null!=e?(be(this,t,e),c.updateOffset(this,n),this):xe(this,t)}}function xe(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function be(e,t,n){e.isValid()&&!isNaN(n)&&("FullYear"===t&&ke(e.year())&&1===e.month()&&29===e.date()?e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),Pe(n,e.month())):e._d["set"+(e._isUTC?"UTC":"")+t](n))}function Pe(e,t){if(isNaN(e)||isNaN(t))return NaN;var n,s=(t%(n=12)+n)%n;return e+=(t-s)/12,1===s?ke(e)?29:28:31-s%7%2}Ye=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var t;for(t=0;t<this.length;++t)if(this[t]===e)return t;return-1},I("M",["MM",2],"Mo",function(){return this.month()+1}
vendor: 4,405 bytes, line 9245
9245),I("MMM",0,0,function(e){return this.localeData().monthsShort(this,e)}),I("MMMM",0,0,function(e){return this.localeData().months(this,e)}),H("month","M"),L("month",8),ue("M",B),ue("MM",B,z),ue("MMM",function(e,t){return t.monthsShortRegex(e)}),ue("MMMM",function(e,t){return t.monthsRegex(e)}),ce(["M","MM"],function(e,t){t[_e]=k(e)-1}),ce(["MMM","MMMM"],function(e,t,n,s){var i=n._locale.monthsParse(e,s,n._strict);null!=i?t[_e]=i:g(n).invalidMonth=e});var We=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,He="January_February_March_April_May_June_July_August_September_October_November_December".split("_");var Re="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_");function Ce(e,t){var n;if(!e.isValid())return e;if("string"==typeof t)if(/^\d+$/.test(t))t=k(t);else if(!d(t=e.localeData().monthsParse(t)))return e;return n=Math.min(e.date(),Pe(e.year(),t)),e._d["set"+(e._isUTC?"UTC":"")+"Month"](t,n),e}function Fe(e){return null!=e?(Ce(this,e),c.updateOffset(this,!0),this):xe(this,"Month")}var Le=ae;var Ue=ae;function Ne(){function e(e,t){return t.length-e.length}var t,n,s=[],i=[],r=[];for(t=0;t<12;t++)n=y([2e3,t]),s.push(this.monthsShort(n,"")),i.push(this.months(n,"")),r.push(this.months(n,"")),r.push(this.monthsShort(n,""));for(s.sort(e),i.sort(e),r.sort(e),t=0;t<12;t++)s[t]=de(s[t]),i[t]=de(i[t]);for(t=0;t<24;t++)r[t]=de(r[t]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+s.join("|")+")","i")}function Ge(e){var t=new Date(Date.UTC.apply(null,arguments));return e<100&&0<=e&&isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e),t}function Ve(e,t,n){var s=7+t-n;return-((7+Ge(e,0,s).getUTCDay()-t)%7)+s-1}function Ee(e,t,n,s,i){var r,a,o=1+7*(t-1)+(7+n-s)%7+Ve(e,s,i);return o<=0?a=De(r=e-1)+o:o>De(e)?(r=e+1,a=o-De(e)):(r=e,a=o),{year:r,dayOfYear:a}}function Ie(e,t,n){var s,i,r=Ve(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?s=a+Ae(i=e.year()-1,t,n):a>Ae(e.year(),t,n)?(s=a-Ae(e.year(),t,n),i=e.year()+1):(i=e.year(),s=a),{week:s,year:i}}function Ae(e,t,n){var s=Ve(e,t,n),i=Ve(e+1,t,n);return(De(e)-s+i)/7}I("w",["ww",2],"wo","week"),I("W",["WW",2],"Wo","isoWeek"),H("week","w"),H("isoWeek","W"),L("week",5),L("isoWeek",5),ue("w",B),ue("ww",B,z),ue("W",B),ue("WW",B,z),fe(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=k(e)});I("d",0,"do","day"),I("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),I("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),I("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),I("e",0,0,"weekday"),I("E",0,0,"isoWeekday"),H("day","d"),H("weekday","e"),H("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),ue("d",B),ue("e",B),ue("E",B),ue("dd",function(e,t){return t.weekdaysMinRegex(e)}),ue("ddd",function(e,t){return t.weekdaysShortRegex(e)}),ue("dddd",function(e,t){return t.weekdaysRegex(e)}),fe(["dd","ddd","dddd"],function(e,t,n,s){var i=n._locale.weekdaysParse(e,s,n._strict);null!=i?t.d=i:g(n).invalidWeekday=e}),fe(["d","e","E"],function(e,t,n,s){t[s]=k(e)});var je="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");var Ze="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");var ze="Su_Mo_Tu_We_Th_Fr_Sa".split("_");var $e=ae;var qe=ae;var Je=ae;function Be(){function e(e,t){return t.length-e.length}var t,n,s,i,r,a=[],o=[],u=[],l=[];for(t=0;t<7;t++)n=y([2e3,1]).day(t),s=this.weekdaysMin(n,""),i=this.weekdaysShort(n,""),r=this.weekdays(n,""),a.push(s),o.push(i),u.push(r),l.push(s),l.push(i),l.push(r);for(a.sort(e),o.sort(e),u.sort(e),l.sort(e),t=0;t<7;t++)o[t]=de(o[t]),u[t]=de(u[t]),l[t]=de(l[t]);this._weekdaysRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+a.join("|")+")","i")}function Qe(){return this.hours()%12||12}function Xe(e,t){I(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Ke(e,t){return t._meridiemParse}I("H",["HH",2],0,"hour"),I("h",["hh",2],0,Qe),I("k",["kk",2],0,function(){return this.hours()||24}),I("hmm",0,0,function(){return""+Qe.apply(this)+U(this.minutes(),2)}
vendor: 5,168 bytes, line 9245
9245),I("hmmss",0,0,function(){return""+Qe.apply(this)+U(this.minutes(),2)+U(this.seconds(),2)}),I("Hmm",0,0,function(){return""+this.hours()+U(this.minutes(),2)}),I("Hmmss",0,0,function(){return""+this.hours()+U(this.minutes(),2)+U(this.seconds(),2)}),Xe("a",!0),Xe("A",!1),H("hour","h"),L("hour",13),ue("a",Ke),ue("A",Ke),ue("H",B),ue("h",B),ue("k",B),ue("HH",B,z),ue("hh",B,z),ue("kk",B,z),ue("hmm",Q),ue("hmmss",X),ue("Hmm",Q),ue("Hmmss",X),ce(["H","HH"],ge),ce(["k","kk"],function(e,t,n){var s=k(e);t[ge]=24===s?0:s}),ce(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),ce(["h","hh"],function(e,t,n){t[ge]=k(e),g(n).bigHour=!0}),ce("hmm",function(e,t,n){var s=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s)),g(n).bigHour=!0}),ce("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s,2)),t[ve]=k(e.substr(i)),g(n).bigHour=!0}),ce("Hmm",function(e,t,n){var s=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s))}),ce("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s,2)),t[ve]=k(e.substr(i))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:He,monthsShort:Re,week:{dow:0,doy:6},weekdays:je,weekdaysMin:ze,weekdaysShort:Ze,meridiemParse:/[ap]\.?m?\.?/i},st={},it={};function rt(e){return e?e.toLowerCase().replace("_","-"):e}function at(e){var t=null;if(!st[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),ot(t)}catch(e){}return st[e]}function ot(e,t){var n;return e&&((n=l(t)?lt(e):ut(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function ut(e,t){if(null!==t){var n,s=nt;if(t.abbr=e,null!=st[e])T("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=st[e]._config;else if(null!=t.parentLocale)if(null!=st[t.parentLocale])s=st[t.parentLocale]._config;else{if(null==(n=at(t.parentLocale)))return it[t.parentLocale]||(it[t.parentLocale]=[]),it[t.parentLocale].push({name:e,config:t}),null;s=n._config}return st[e]=new P(b(s,t)),it[e]&&it[e].forEach(function(e){ut(e.name,e.config)}),ot(e),st[e]}return delete st[e],null}function lt(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!o(e)){if(t=at(e))return t;e=[e]}return function(e){for(var t,n,s,i,r=0;r<e.length;){for(t=(i=rt(e[r]).split("-")).length,n=(n=rt(e[r+1]))?n.split("-"):null;0<t;){if(s=at(i.slice(0,t).join("-")))return s;if(n&&n.length>=t&&a(i,n,!0)>=t-1)break;t--}r++}return et}(e)}function dt(e){var t,n=e._a;return n&&-2===g(e).overflow&&(t=n[_e]<0||11<n[_e]?_e:n[ye]<1||n[ye]>Pe(n[me],n[_e])?ye:n[ge]<0||24<n[ge]||24===n[ge]&&(0!==n[pe]||0!==n[ve]||0!==n[we])?ge:n[pe]<0||59<n[pe]?pe:n[ve]<0||59<n[ve]?ve:n[we]<0||999<n[we]?we:-1,g(e)._overflowDayOfYear&&(t<me||ye<t)&&(t=ye),g(e)._overflowWeeks&&-1===t&&(t=Me),g(e)._overflowWeekday&&-1===t&&(t=Se),g(e).overflow=t),e}function ht(e,t,n){return null!=e?e:null!=t?t:n}function ct(e){var t,n,s,i,r,a=[];if(!e._d){var o,u;for(o=e,u=new Date(c.now()),s=o._useUTC?[u.getUTCFullYear(),u.getUTCMonth(),u.getUTCDate()]:[u.getFullYear(),u.getMonth(),u.getDate()],e._w&&null==e._a[ye]&&null==e._a[_e]&&function(e){var t,n,s,i,r,a,o,u;if(null!=(t=e._w).GG||null!=t.W||null!=t.E)r=1,a=4,n=ht(t.GG,e._a[me],Ie(Tt(),1,4).year),s=ht(t.W,1),((i=ht(t.E,1))<1||7<i)&&(u=!0);else{r=e._locale._week.dow,a=e._locale._week.doy;var l=Ie(Tt(),r,a);n=ht(t.gg,e._a[me],l.year),s=ht(t.w,l.week),null!=t.d?((i=t.d)<0||6<i)&&(u=!0):null!=t.e?(i=t.e+r,(t.e<0||6<t.e)&&(u=!0)):i=r}s<1||s>Ae(n,r,a)?g(e)._overflowWeeks=!0:null!=u?g(e)._overflowWeekday=!0:(o=Ee(n,s,i,r,a),e._a[me]=o.year,e._dayOfYear=o.dayOfYear)}(e),null!=e._dayOfYear&&(r=ht(e._a[me],s[me]),(e._dayOfYear>De(r)||0===e._dayOfYear)&&(g(e)._overflowDayOfYear=!0),n=Ge(r,0,e._dayOfYear),e._a[_e]=n.getUTCMonth(),e._a[ye]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=a[t]=s[t];for(;t<7;t++)e._a[t]=a[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[pe]&&0===e._a[ve]&&0===e._a[we]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Ge:function(e,t,n,s,i,r,a){var o=new Date(e,t,n,s,i,r,a);return e<100&&0<=e&&isFinite(o.getFullYear())&&o.setFullYear(e),o}).apply(null,a),i=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==i&&(g(e).weekdayMismatch=!0)}}
vendor: 7,222 bytes, line 9245
9245var ft=/^\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)?)?$/,mt=/^\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)?)?$/,_t=/Z|[+-]\d\d(?::?\d\d)?/,yt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],gt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],pt=/^\/?Date\((\-?\d+)/i;function vt(e){var t,n,s,i,r,a,o=e._i,u=ft.exec(o)||mt.exec(o);if(u){for(g(e).iso=!0,t=0,n=yt.length;t<n;t++)if(yt[t][1].exec(u[1])){i=yt[t][0],s=!1!==yt[t][2];break}if(null==i)return void(e._isValid=!1);if(u[3]){for(t=0,n=gt.length;t<n;t++)if(gt[t][1].exec(u[3])){r=(u[2]||" ")+gt[t][0];break}if(null==r)return void(e._isValid=!1)}if(!s&&null!=r)return void(e._isValid=!1);if(u[4]){if(!_t.exec(u[4]))return void(e._isValid=!1);a="Z"}e._f=i+(r||"")+(a||""),kt(e)}else e._isValid=!1}var wt=/^(?:(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}))$/;function Mt(e,t,n,s,i,r){var a=[function(e){var t=parseInt(e,10);{if(t<=49)return 2e3+t;if(t<=999)return 1900+t}return t}(e),Re.indexOf(t),parseInt(n,10),parseInt(s,10),parseInt(i,10)];return r&&a.push(parseInt(r,10)),a}var St={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function Dt(e){var t,n,s,i=wt.exec(e._i.replace(/\([^)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s\s*/,"").replace(/\s\s*$/,""));if(i){var r=Mt(i[4],i[3],i[2],i[5],i[6],i[7]);if(t=i[1],n=r,s=e,t&&Ze.indexOf(t)!==new Date(n[0],n[1],n[2]).getDay()&&(g(s).weekdayMismatch=!0,!(s._isValid=!1)))return;e._a=r,e._tzm=function(e,t,n){if(e)return St[e];if(t)return 0;var s=parseInt(n,10),i=s%100;return(s-i)/100*60+i}(i[8],i[9],i[10]),e._d=Ge.apply(null,e._a),e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),g(e).rfc2822=!0}else e._isValid=!1}function kt(e){if(e._f!==c.ISO_8601)if(e._f!==c.RFC_2822){e._a=[],g(e).empty=!0;var t,n,s,i,r,a,o,u,l=""+e._i,d=l.length,h=0;for(s=j(e._f,e._locale).match(N)||[],t=0;t<s.length;t++)i=s[t],(n=(l.match(le(i,e))||[])[0])&&(0<(r=l.substr(0,l.indexOf(n))).length&&g(e).unusedInput.push(r),l=l.slice(l.indexOf(n)+n.length),h+=n.length),E[i]?(n?g(e).empty=!1:g(e).unusedTokens.push(i),a=i,u=e,null!=(o=n)&&m(he,a)&&he[a](o,u._a,u,a)):e._strict&&!n&&g(e).unusedTokens.push(i);g(e).charsLeftOver=d-h,0<l.length&&g(e).unusedInput.push(l),e._a[ge]<=12&&!0===g(e).bigHour&&0<e._a[ge]&&(g(e).bigHour=void 0),g(e).parsedDateParts=e._a.slice(0),g(e).meridiem=e._meridiem,e._a[ge]=function(e,t,n){var s;if(null==n)return t;return null!=e.meridiemHour?e.meridiemHour(t,n):(null!=e.isPM&&((s=e.isPM(n))&&t<12&&(t+=12),s||12!==t||(t=0)),t)}(e._locale,e._a[ge],e._meridiem),ct(e),dt(e)}else Dt(e);else vt(e)}function Yt(e){var t,n,s,i,r=e._i,a=e._f;return e._locale=e._locale||lt(e._l),null===r||void 0===a&&""===r?v({nullInput:!0}):("string"==typeof r&&(e._i=r=e._locale.preparse(r)),S(r)?new M(dt(r)):(h(r)?e._d=r:o(a)?function(e){var t,n,s,i,r;if(0===e._f.length)return g(e).invalidFormat=!0,e._d=new Date(NaN);for(i=0;i<e._f.length;i++)r=0,t=w({},e),null!=e._useUTC&&(t._useUTC=e._useUTC),t._f=e._f[i],kt(t),p(t)&&(r+=g(t).charsLeftOver,r+=10*g(t).unusedTokens.length,g(t).score=r,(null==s||r<s)&&(s=r,n=t));_(e,n||t)}(e):a?kt(e):l(n=(t=e)._i)?t._d=new Date(c.now()):h(n)?t._d=new Date(n.valueOf()):"string"==typeof n?(s=t,null===(i=pt.exec(s._i))?(vt(s),!1===s._isValid&&(delete s._isValid,Dt(s),!1===s._isValid&&(delete s._isValid,c.createFromInputFallback(s)))):s._d=new Date(+i[1])):o(n)?(t._a=f(n.slice(0),function(e){return parseInt(e,10)}),ct(t)):u(n)?function(e){if(!e._d){var t=C(e._i);e._a=f([t.year,t.month,t.day||t.date,t.hour,t.minute,t.second,t.millisecond],function(e){return e&&parseInt(e,10)}),ct(e)}}(t):d(n)?t._d=new Date(n):c.createFromInputFallback(t),p(e)||(e._d=null),e))}function Ot(e,t,n,s,i){var r,a={};return!0!==n&&!1!==n||(s=n,n=void 0),(u(e)&&function(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var t;for(t in e)if(e.hasOwnProperty(t))return!1;return!0}(e)||o(e)&&0===e.length)&&(e=void 0),a._isAMomentObject=!0,a._useUTC=a._isUTC=i,a._l=n,a._i=e,a._f=t,a._strict=s,(r=new M(dt(Yt(a))))._nextDay&&(r.add(1,"d"),r._nextDay=void 0),r}function Tt(e,t,n,s){return Ot(e,t,n,s,!1)}c.createFromInputFallback=n("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(e){e._d=new Date(e._i+(e._useUTC?" UTC":""))}),c.ISO_8601=function(){},c.RFC_2822=function(){};var xt=n("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=Tt.apply(null,arguments);return this.isValid()&&e.isValid()?e<this?this:e:v()}),bt=n("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=Tt.apply(null,arguments);return this.isValid()&&e.isValid()?this<e?this:e:v()});function Pt(e,t){var n,s;if(1===t.length&&o(t[0])&&(t=t[0]),!t.length)return Tt();for(n=t[0],s=1;s<t.length;++s)t[s].isValid()&&!t[s][e](n)||(n=t[s]);return n}var Wt=["year","quarter","month","week","day","hour","minute","second","millisecond"];function Ht(e){var t=C(e),n=t.year||0,s=t.quarter||0,i=t.month||0,r=t.week||0,a=t.day||0,o=t.hour||0,u=t.minute||0,l=t.second||0,d=t.millisecond||0;this._isValid=function(e){for(var t in e)if(-1===Ye.call(Wt,t)||null!=e[t]&&isNaN(e[t]))return!1;for(var n=!1,s=0;s<Wt.length;++s)if(e[Wt[s]]){if(n)return!1;parseFloat(e[Wt[s]])!==k(e[Wt[s]])&&(n=!0)}return!0}(t),this._milliseconds=+d+1e3*l+6e4*u+1e3*o*60*60,this._days=+a+7*r,this._months=+i+3*s+12*n,this._data={},this._locale=lt(),this._bubble()}function Rt(e){return e instanceof Ht}function Ct(e){return e<0?-1*Math.round(-1*e):Math.round(e)}function Ft(e,n){I(e,0,0,function(){var e=this.utcOffset(),t="+";return e<0&&(e=-e,t="-"),t+U(~~(e/60),2)+n+U(~~e%60,2)})}Ft("Z",":"),Ft("ZZ",""),ue("Z",re),ue("ZZ",re),ce(["Z","ZZ"],function(e,t,n){n._useUTC=!0,n._tzm=Ut(re,e)});var Lt=/([\+\-]|\d\d)/gi;function Ut(e,t){var n=(t||"").match(e);if(null===n)return null;var s=((n[n.length-1]||[])+"").match(Lt)||["-",0,0],i=60*s[1]+k(s[2]);return 0===i?0:"+"===s[0]?i:-i}function Nt(e,t){var n,s;return t._isUTC?(n=t.clone(),s=(S(e)||h(e)?e.valueOf():Tt(e).valueOf())-n.valueOf(),n._d.setTime(n._d.valueOf()+s),c.updateOffset(n,!1),n):Tt(e).local()}
vendor: 25,358 bytes, line 9245
9245function Gt(e){return 15*-Math.round(e._d.getTimezoneOffset()/15)}function Vt(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}c.updateOffset=function(){};var Et=/^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,It=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function At(e,t){var n,s,i,r=e,a=null;return Rt(e)?r={ms:e._milliseconds,d:e._days,M:e._months}:d(e)?(r={},t?r[t]=e:r.milliseconds=e):(a=Et.exec(e))?(n="-"===a[1]?-1:1,r={y:0,d:k(a[ye])*n,h:k(a[ge])*n,m:k(a[pe])*n,s:k(a[ve])*n,ms:k(Ct(1e3*a[we]))*n}):(a=It.exec(e))?(n="-"===a[1]?-1:(a[1],1),r={y:jt(a[2],n),M:jt(a[3],n),w:jt(a[4],n),d:jt(a[5],n),h:jt(a[6],n),m:jt(a[7],n),s:jt(a[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(i=function(e,t){var n;if(!e.isValid()||!t.isValid())return{milliseconds:0,months:0};t=Nt(t,e),e.isBefore(t)?n=Zt(e,t):((n=Zt(t,e)).milliseconds=-n.milliseconds,n.months=-n.months);return n}(Tt(r.from),Tt(r.to)),(r={}).ms=i.milliseconds,r.M=i.months),s=new Ht(r),Rt(e)&&m(e,"_locale")&&(s._locale=e._locale),s}function jt(e,t){var n=e&&parseFloat(e.replace(",","."));return(isNaN(n)?0:n)*t}function Zt(e,t){var n={milliseconds:0,months:0};return n.months=t.month()-e.month()+12*(t.year()-e.year()),e.clone().add(n.months,"M").isAfter(t)&&--n.months,n.milliseconds=+t-+e.clone().add(n.months,"M"),n}function zt(s,i){return function(e,t){var n;return null===t||isNaN(+t)||(T(i,"moment()."+i+"(period, number) is deprecated. Please use moment()."+i+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),n=e,e=t,t=n),$t(this,At(e="string"==typeof e?+e:e,t),s),this}}function $t(e,t,n,s){var i=t._milliseconds,r=Ct(t._days),a=Ct(t._months);e.isValid()&&(s=null==s||s,a&&Ce(e,xe(e,"Month")+a*n),r&&be(e,"Date",xe(e,"Date")+r*n),i&&e._d.setTime(e._d.valueOf()+i*n),s&&c.updateOffset(e,r||a))}At.fn=Ht.prototype,At.invalid=function(){return At(NaN)};var qt=zt(1,"add"),Jt=zt(-1,"subtract");function Bt(e,t){var n=12*(t.year()-e.year())+(t.month()-e.month()),s=e.clone().add(n,"months");return-(n+(t-s<0?(t-s)/(s-e.clone().add(n-1,"months")):(t-s)/(e.clone().add(n+1,"months")-s)))||0}function Qt(e){var t;return void 0===e?this._locale._abbr:(null!=(t=lt(e))&&(this._locale=t),this)}c.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",c.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Xt=n("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)});function Kt(){return this._locale}function en(e,t){I(0,[e,e.length],0,t)}function tn(e,t,n,s,i){var r;return null==e?Ie(this,s,i).year:((r=Ae(e,s,i))<t&&(t=r),function(e,t,n,s,i){var r=Ee(e,t,n,s,i),a=Ge(r.year,0,r.dayOfYear);return this.year(a.getUTCFullYear()),this.month(a.getUTCMonth()),this.date(a.getUTCDate()),this}.call(this,e,t,n,s,i))}I(0,["gg",2],0,function(){return this.weekYear()%100}),I(0,["GG",2],0,function(){return this.isoWeekYear()%100}),en("gggg","weekYear"),en("ggggg","weekYear"),en("GGGG","isoWeekYear"),en("GGGGG","isoWeekYear"),H("weekYear","gg"),H("isoWeekYear","GG"),L("weekYear",1),L("isoWeekYear",1),ue("G",se),ue("g",se),ue("GG",B,z),ue("gg",B,z),ue("GGGG",ee,q),ue("gggg",ee,q),ue("GGGGG",te,J),ue("ggggg",te,J),fe(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,s){t[s.substr(0,2)]=k(e)}),fe(["gg","GG"],function(e,t,n,s){t[s]=c.parseTwoDigitYear(e)}),I("Q",0,"Qo","quarter"),H("quarter","Q"),L("quarter",7),ue("Q",Z),ce("Q",function(e,t){t[_e]=3*(k(e)-1)}),I("D",["DD",2],"Do","date"),H("date","D"),L("date",9),ue("D",B),ue("DD",B,z),ue("Do",function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),ce(["D","DD"],ye),ce("Do",function(e,t){t[ye]=k(e.match(B)[0])});var nn=Te("Date",!0);I("DDD",["DDDD",3],"DDDo","dayOfYear"),H("dayOfYear","DDD"),L("dayOfYear",4),ue("DDD",K),ue("DDDD",$),ce(["DDD","DDDD"],function(e,t,n){n._dayOfYear=k(e)}),I("m",["mm",2],0,"minute"),H("minute","m"),L("minute",14),ue("m",B),ue("mm",B,z),ce(["m","mm"],pe);var sn=Te("Minutes",!1);I("s",["ss",2],0,"second"),H("second","s"),L("second",15),ue("s",B),ue("ss",B,z),ce(["s","ss"],ve);var rn,an=Te("Seconds",!1);for(I("S",0,0,function(){return~~(this.millisecond()/100)}),I(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),I(0,["SSS",3],0,"millisecond"),I(0,["SSSS",4],0,function(){return 10*this.millisecond()}),I(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),I(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),I(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),I(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),I(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),H("millisecond","ms"),L("millisecond",16),ue("S",K,Z),ue("SS",K,z),ue("SSS",K,$),rn="SSSS";rn.length<=9;rn+="S")ue(rn,ne);function on(e,t){t[we]=k(1e3*("0."+e))}for(rn="S";rn.length<=9;rn+="S")ce(rn,on);var un=Te("Milliseconds",!1);I("z",0,0,"zoneAbbr"),I("zz",0,0,"zoneName");var ln=M.prototype;function dn(e){return e}ln.add=qt,ln.calendar=function(e,t){var n=e||Tt(),s=Nt(n,this).startOf("day"),i=c.calendarFormat(this,s)||"sameElse",r=t&&(x(t[i])?t[i].call(this,n):t[i]);return this.format(r||this.localeData().calendar(i,this,Tt(n)))},ln.clone=function(){return new M(this)},ln.diff=function(e,t,n){var s,i,r;if(!this.isValid())return NaN;if(!(s=Nt(e,this)).isValid())return NaN;switch(i=6e4*(s.utcOffset()-this.utcOffset()),t=R(t)){case"year":r=Bt(this,s)/12;break;case"month":r=Bt(this,s);break;case"quarter":r=Bt(this,s)/3;break;case"second":r=(this-s)/1e3;break;case"minute":r=(this-s)/6e4;break;case"hour":r=(this-s)/36e5;break;case"day":r=(this-s-i)/864e5;break;case"week":r=(this-s-i)/6048e5;break;default:r=this-s}return n?r:D(r)},ln.endOf=function(e){return void 0===(e=R(e))||"millisecond"===e?this:("date"===e&&(e="day"),this.startOf(e).add(1,"isoWeek"===e?"week":e).subtract(1,"ms"))},ln.format=function(e){e||(e=this.isUtc()?c.defaultFormatUtc:c.defaultFormat);var t=A(this,e);return this.localeData().postformat(t)},ln.from=function(e,t){return this.isValid()&&(S(e)&&e.isValid()||Tt(e).isValid())?At({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},ln.fromNow=function(e){return this.from(Tt(),e)},ln.to=function(e,t){return this.isValid()&&(S(e)&&e.isValid()||Tt(e).isValid())?At({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},ln.toNow=function(e){return this.to(Tt(),e)},ln.get=function(e){return x(this[e=R(e)])?this[e]():this},ln.invalidAt=function(){return g(this).overflow},ln.isAfter=function(e,t){var n=S(e)?e:Tt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=R(l(t)?"millisecond":t))?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(t).valueOf())},ln.isBefore=function(e,t){var n=S(e)?e:Tt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=R(l(t)?"millisecond":t))?this.valueOf()<n.valueOf():this.clone().endOf(t).valueOf()<n.valueOf())},ln.isBetween=function(e,t,n,s){return("("===(s=s||"()")[0]?this.isAfter(e,n):!this.isBefore(e,n))&&(")"===s[1]?this.isBefore(t,n):!this.isAfter(t,n))},ln.isSame=function(e,t){var n,s=S(e)?e:Tt(e);return!(!this.isValid()||!s.isValid())&&("millisecond"===(t=R(t||"millisecond"))?this.valueOf()===s.valueOf():(n=s.valueOf(),this.clone().startOf(t).valueOf()<=n&&n<=this.clone().endOf(t).valueOf()))},ln.isSameOrAfter=function(e,t){return this.isSame(e,t)||this.isAfter(e,t)},ln.isSameOrBefore=function(e,t){return this.isSame(e,t)||this.isBefore(e,t)},ln.isValid=function(){return p(this)},ln.lang=Xt,ln.locale=Qt,ln.localeData=Kt,ln.max=bt,ln.min=xt,ln.parsingFlags=function(){return _({},g(this))},ln.set=function(e,t){if("object"==typeof e)for(var n=function(e){var t=[];for(var n in e)t.push({unit:n,priority:F[n]});return t.sort(function(e,t){return e.priority-t.priority}),t}(e=C(e)),s=0;s<n.length;s++)this[n[s].unit](e[n[s].unit]);else if(x(this[e=R(e)]))return this[e](t);return this},ln.startOf=function(e){switch(e=R(e)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===e&&this.weekday(0),"isoWeek"===e&&this.isoWeekday(1),"quarter"===e&&this.month(3*Math.floor(this.month()/3)),this},ln.subtract=Jt,ln.toArray=function(){var e=this;return[e.year(),e.month(),e.date(),e.hour(),e.minute(),e.second(),e.millisecond()]},ln.toObject=function(){var e=this;return{years:e.year(),months:e.month(),date:e.date(),hours:e.hours(),minutes:e.minutes(),seconds:e.seconds(),milliseconds:e.milliseconds()}},ln.toDate=function(){return new Date(this.valueOf())},ln.toISOString=function(e){if(!this.isValid())return null;var t=!0!==e,n=t?this.clone().utc():this;return n.year()<0||9999<n.year()?A(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):x(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",A(n,"Z")):A(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},ln.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e="moment",t="";this.isLocal()||(e=0===this.utcOffset()?"moment.utc":"moment.parseZone",t="Z");var n="["+e+'("]',s=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",i=t+'[")]';return this.format(n+s+"-MM-DD[T]HH:mm:ss.SSS"+i)},ln.toJSON=function(){return this.isValid()?this.toISOString():null},ln.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},ln.unix=function(){return Math.floor(this.valueOf()/1e3)},ln.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},ln.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},ln.year=Oe,ln.isLeapYear=function(){return ke(this.year())},ln.weekYear=function(e){return tn.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},ln.isoWeekYear=function(e){return tn.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},ln.quarter=ln.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},ln.month=Fe,ln.daysInMonth=function(){return Pe(this.year(),this.month())},ln.week=ln.weeks=function(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")},ln.isoWeek=ln.isoWeeks=function(e){var t=Ie(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")},ln.weeksInYear=function(){var e=this.localeData()._week;return Ae(this.year(),e.dow,e.doy)},ln.isoWeeksInYear=function(){return Ae(this.year(),1,4)},ln.date=nn,ln.day=ln.days=function(e){if(!this.isValid())return null!=e?this:NaN;var t,n,s=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(t=e,n=this.localeData(),e="string"!=typeof t?t:isNaN(t)?"number"==typeof(t=n.weekdaysParse(t))?t:null:parseInt(t,10),this.add(e-s,"d")):s},ln.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")},ln.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null!=e){var t=(n=e,s=this.localeData(),"string"==typeof n?s.weekdaysParse(n)%7||7:isNaN(n)?null:n);return this.day(this.day()%7?t:t-7)}return this.day()||7;var n,s},ln.dayOfYear=function(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")},ln.hour=ln.hours=tt,ln.minute=ln.minutes=sn,ln.second=ln.seconds=an,ln.millisecond=ln.milliseconds=un,ln.utcOffset=function(e,t,n){var s,i=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null!=e){if("string"==typeof e){if(null===(e=Ut(re,e)))return this}else Math.abs(e)<16&&!n&&(e*=60);return!this._isUTC&&t&&(s=Gt(this)),this._offset=e,this._isUTC=!0,null!=s&&this.add(s,"m"),i!==e&&(!t||this._changeInProgress?$t(this,At(e-i,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,c.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?i:Gt(this)},ln.utc=function(e){return this.utcOffset(0,e)},ln.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Gt(this),"m")),this},ln.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var e=Ut(ie,this._i);null!=e?this.utcOffset(e):this.utcOffset(0,!0)}return this},ln.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?Tt(e).utcOffset():0,(this.utcOffset()-e)%60==0)},ln.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},ln.isLocal=function(){return!!this.isValid()&&!this._isUTC},ln.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},ln.isUtc=Vt,ln.isUTC=Vt,ln.zoneAbbr=function(){return this._isUTC?"UTC":""},ln.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},ln.dates=n("dates accessor is deprecated. Use date instead.",nn),ln.months=n("months accessor is deprecated. Use month instead",Fe),ln.years=n("years accessor is deprecated. Use year instead",Oe),ln.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),ln.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!l(this._isDSTShifted))return this._isDSTShifted;var e={};if(w(e,this),(e=Yt(e))._a){var t=e._isUTC?y(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0<a(e._a,t.toArray())}else this._isDSTShifted=!1;return this._isDSTShifted});var hn=P.prototype;function cn(e,t,n,s){var i=lt(),r=y().set(s,t);return i[n](r,e)}function fn(e,t,n){if(d(e)&&(t=e,e=void 0),e=e||"",null!=t)return cn(e,t,n,"month");var s,i=[];for(s=0;s<12;s++)i[s]=cn(e,s,n,"month");return i}function mn(e,t,n,s){"boolean"==typeof e?d(t)&&(n=t,t=void 0):(t=e,e=!1,d(n=t)&&(n=t,t=void 0)),t=t||"";var i,r=lt(),a=e?r._week.dow:0;if(null!=n)return cn(t,(n+a)%7,s,"day");var o=[];for(i=0;i<7;i++)o[i]=cn(t,(i+a)%7,s,"day");return o}hn.calendar=function(e,t,n){var s=this._calendar[e]||this._calendar.sameElse;return x(s)?s.call(t,n):s},hn.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.replace(/MMMM|MM|DD|dddd/g,function(e){return e.slice(1)}),this._longDateFormat[e])},hn.invalidDate=function(){return this._invalidDate},hn.ordinal=function(e){return this._ordinal.replace("%d",e)},hn.preparse=dn,hn.postformat=dn,hn.relativeTime=function(e,t,n,s){var i=this._relativeTime[n];return x(i)?i(e,t,n,s):i.replace(/%d/i,e)},hn.pastFuture=function(e,t){var n=this._relativeTime[0<e?"future":"past"];return x(n)?n(t):n.replace(/%s/i,t)},hn.set=function(e){var t,n;for(n in e)x(t=e[n])?this[n]=t:this["_"+n]=t;this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},hn.months=function(e,t){return e?o(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||We).test(t)?"format":"standalone"][e.month()]:o(this._months)?this._months:this._months.standalone},hn.monthsShort=function(e,t){return e?o(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[We.test(t)?"format":"standalone"][e.month()]:o(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},hn.monthsParse=function(e,t,n){var s,i,r;if(this._monthsParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],s=0;s<12;++s)r=y([2e3,s]),this._shortMonthsParse[s]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[s]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===t?-1!==(i=Ye.call(this._shortMonthsParse,a))?i:null:-1!==(i=Ye.call(this._longMonthsParse,a))?i:null:"MMM"===t?-1!==(i=Ye.call(this._shortMonthsParse,a))?i:-1!==(i=Ye.call(this._longMonthsParse,a))?i:null:-1!==(i=Ye.call(this._longMonthsParse,a))?i:-1!==(i=Ye.call(this._shortMonthsParse,a))?i:null}.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),s=0;s<12;s++){if(i=y([2e3,s]),n&&!this._longMonthsParse[s]&&(this._longMonthsParse[s]=new RegExp("^"+this.months(i,"").replace(".","")+"$","i"),this._shortMonthsParse[s]=new RegExp("^"+this.monthsShort(i,"").replace(".","")+"$","i")),n||this._monthsParse[s]||(r="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[s]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===t&&this._longMonthsParse[s].test(e))return s;if(n&&"MMM"===t&&this._shortMonthsParse[s].test(e))return s;if(!n&&this._monthsParse[s].test(e))return s}},hn.monthsRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||Ne.call(this),e?this._monthsStrictRegex:this._monthsRegex):(m(this,"_monthsRegex")||(this._monthsRegex=Ue),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},hn.monthsShortRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||Ne.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(m(this,"_monthsShortRegex")||(this._monthsShortRegex=Le),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},hn.week=function(e){return Ie(e,this._week.dow,this._week.doy).week},hn.firstDayOfYear=function(){return this._week.doy},hn.firstDayOfWeek=function(){return this._week.dow},hn.weekdays=function(e,t){return e?o(this._weekdays)?this._weekdays[e.day()]:this._weekdays[this._weekdays.isFormat.test(t)?"format":"standalone"][e.day()]:o(this._weekdays)?this._weekdays:this._weekdays.standalone},hn.weekdaysMin=function(e){return e?this._weekdaysMin[e.day()]:this._weekdaysMin},hn.weekdaysShort=function(e){return e?this._weekdaysShort[e.day()]:this._weekdaysShort},hn.weekdaysParse=function(e,t,n){var s,i,r;if(this._weekdaysParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],s=0;s<7;++s)r=y([2e3,1]).day(s),this._minWeekdaysParse[s]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[s]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[s]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===t?-1!==(i=Ye.call(this._weekdaysParse,a))?i:null:"ddd"===t?-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:null:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:"dddd"===t?-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:"ddd"===t?-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:null}.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),s=0;s<7;s++){if(i=y([2e3,1]).day(s),n&&!this._fullWeekdaysParse[s]&&(this._fullWeekdaysParse[s]=new RegExp("^"+this.weekdays(i,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[s]=new RegExp("^"+this.weekdaysShort(i,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[s]=new RegExp("^"+this.weekdaysMin(i,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[s]||(r="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[s]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[s].test(e))return s;if(n&&"ddd"===t&&this._shortWeekdaysParse[s].test(e))return s;if(n&&"dd"===t&&this._minWeekdaysParse[s].test(e))return s;if(!n&&this._weekdaysParse[s].test(e))return s}},hn.weekdaysRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(m(this,"_weekdaysRegex")||(this._weekdaysRegex=$e),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},hn.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(m(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=qe),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},hn.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(m(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Je),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},hn.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},hn.meridiem=function(e,t,n){return 11<e?n?"pm":"PM":n?"am":"AM"},ot("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===k(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}}),c.lang=n("moment.lang is deprecated. Use moment.locale instead.",ot),c.langData=n("moment.langData is deprecated. Use moment.localeData instead.",lt);var _n=Math.abs;function yn(e,t,n,s){var i=At(t,n);return e._milliseconds+=s*i._milliseconds,e._days+=s*i._days,e._months+=s*i._months,e._bubble()}function gn(e){return e<0?Math.floor(e):Math.ceil(e)}function pn(e){return 4800*e/146097}function vn(e){return 146097*e/4800}function wn(e){return function(){return this.as(e)}}var Mn=wn("ms"),Sn=wn("s"),Dn=wn("m"),kn=wn("h"),Yn=wn("d"),On=wn("w"),Tn=wn("M"),xn=wn("y");function bn(e){return function(){return this.isValid()?this._data[e]:NaN}}var Pn=bn("milliseconds"),Wn=bn("seconds"),Hn=bn("minutes"),Rn=bn("hours"),Cn=bn("days"),Fn=bn("months"),Ln=bn("years");var Un=Math.round,Nn={ss:44,s:45,m:45,h:22,d:26,M:11};var Gn=Math.abs;function Vn(e){return(0<e)-(e<0)||+e}function En(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n=Gn(this._milliseconds)/1e3,s=Gn(this._days),i=Gn(this._months);t=D((e=D(n/60))/60),n%=60,e%=60;var r=D(i/12),a=i%=12,o=s,u=t,l=e,d=n?n.toFixed(3).replace(/\.?0+$/,""):"",h=this.asSeconds();if(!h)return"P0D";var c=h<0?"-":"",f=Vn(this._months)!==Vn(h)?"-":"",m=Vn(this._days)!==Vn(h)?"-":"",_=Vn(this._milliseconds)!==Vn(h)?"-":"";return c+"P"+(r?f+r+"Y":"")+(a?f+a+"M":"")+(o?m+o+"D":"")+(u||l||d?"T":"")+(u?_+u+"H":"")+(l?_+l+"M":"")+(d?_+d+"S":"")}var In=Ht.prototype;return In.isValid=function(){return this._isValid},In.abs=function(){var e=this._data;return this._milliseconds=_n(this._milliseconds),this._days=_n(this._days),this._months=_n(this._months),e.milliseconds=_n(e.milliseconds),e.seconds=_n(e.seconds),e.minutes=_n(e.minutes),e.hours=_n(e.hours),e.months=_n(e.months),e.years=_n(e.years),this},In.add=function(e,t){return yn(this,e,t,1)},In.subtract=function(e,t){return yn(this,e,t,-1)},In.as=function(e){if(!this.isValid())return NaN;var t,n,s=this._milliseconds;if("month"===(e=R(e))||"year"===e)return t=this._days+s/864e5,n=this._months+pn(t),"month"===e?n:n/12;switch(t=this._days+Math.round(vn(this._months)),e){case"week":return t/7+s/6048e5;case"day":return t+s/864e5;case"hour":return 24*t+s/36e5;case"minute":return 1440*t+s/6e4;case"second":return 86400*t+s/1e3;case"millisecond":return Math.floor(864e5*t)+s;default:throw new Error("Unknown unit "+e)}},In.asMilliseconds=Mn,In.asSeconds=Sn,In.asMinutes=Dn,In.asHours=kn,In.asDays=Yn,In.asWeeks=On,In.asMonths=Tn,In.asYears=xn,In.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*k(this._months/12):NaN},In._bubble=function(){var e,t,n,s,i,r=this._milliseconds,a=this._days,o=this._months,u=this._data;return 0<=r&&0<=a&&0<=o||r<=0&&a<=0&&o<=0||(r+=864e5*gn(vn(o)+a),o=a=0),u.milliseconds=r%1e3,e=D(r/1e3),u.seconds=e%60,t=D(e/60),u.minutes=t%60,n=D(t/60),u.hours=n%24,o+=i=D(pn(a+=D(n/24))),a-=gn(vn(i)),s=D(o/12),o%=12,u.days=a,u.months=o,u.years=s,this},In.clone=function(){return At(this)},In.get=function(e){return e=R(e),this.isValid()?this[e+"s"]():NaN},In.milliseconds=Pn,In.seconds=Wn,In.minutes=Hn,In.hours=Rn,In.days=Cn,In.weeks=function(){return D(this.days()/7)},In.months=Fn,In.years=Ln,In.humanize=function(e){if(!this.isValid())return this.localeData().invalidDate();var t,n,s,i,r,a,o,u,l,d,h,c=this.localeData(),f=(n=!e,s=c,i=At(t=this).abs(),r=Un(i.as("s")),a=Un(i.as("m")),o=Un(i.as("h")),u=Un(i.as("d")),l=Un(i.as("M")),d=Un(i.as("y")),(h=r<=Nn.ss&&["s",r]||r<Nn.s&&["ss",r]||a<=1&&["m"]||a<Nn.m&&["mm",a]||o<=1&&["h"]||o<Nn.h&&["hh",o]||u<=1&&["d"]||u<Nn.d&&["dd",u]||l<=1&&["M"]||l<Nn.M&&["MM",l]||d<=1&&["y"]||["yy",d])[2]=n,h[3]=0<+t,h[4]=s,function(e,t,n,s,i){return i.relativeTime(t||1,!!n,e,s)}.apply(null,h));return e&&(f=c.pastFuture(+this,f)),c.postformat(f)},In.toISOString=En,In.toString=En,In.toJSON=En,In.locale=Qt,In.localeData=Kt,In.toIsoString=n("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",En),In.lang=Xt,I("X",0,0,"unix")
9245,I("x",0,0,"valueOf"),ue("x",se),ue("X",/[+-]?\d+(\.\d{1,3})?/),ce("X",function(e,t,n){n._d=new Date(1e3*parseFloat(e,10))}),ce("x",function(e,t,n){n._d=new Date(k(e))}),c.version="2.22.2",e=Tt,c.fn=ln,c.min=function(){return Pt("isBefore",[].slice.call(arguments,0))},c.max=function(){return Pt("isAfter",[].slice.call(arguments,0))},c.now=function(){return Date.now?Date.now():+new Date},c.utc=y,c.unix=function(e){return Tt(1e3*e)},c.months=function(e,t){return fn(e,t,"months")},c.isDate=h,c.locale=ot,c.invalid=v,c.duration=At,c.isMoment=S,c.weekdays=function(e,t,n){return mn(e,t,n,"weekdays")},c.parseZone=function(){return Tt.apply(null,arguments).parseZone()},c.localeData=lt,c.isDuration=Rt,c.monthsShort=function(e,t){return fn(e,t,"monthsShort")},c.weekdaysMin=function(e,t,n){return mn(e,t,n,"weekdaysMin")},c.defineLocale=ut,c.updateLocale=function(e,t){if(null!=t){var n,s,i=nt;null!=(s=at(e))&&(i=s._config),(n=new P(t=b(i,t))).parentLocale=st[e],st[e]=n,ot(e)}else null!=st[e]&&(null!=st[e].parentLocale?st[e]=st[e].parentLocale:null!=st[e]&&delete st[e]);return st[e]},c.locales=function(){return s(st)},c.weekdaysShort=function(e,t,n){return mn(e,t,n,"weekdaysShort")},c.normalizeUnits=R,c.relativeTimeRounding=function(e){return void 0===e?Un:"function"==typeof e&&(Un=e,!0)},c.relativeTimeThreshold=function(e,t){return void 0!==Nn[e]&&(void 0===t?Nn[e]:(Nn[e]=t,"s"===e&&(Nn.ss=t-1),!0))},c.calendarFormat=function(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},c.prototype=ln,c.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"YYYY-[W]WW",MONTH:"YYYY-MM"},c});
9246(function (root, factory) {
9247	if (typeof define === 'function' && define.amd) {
9248		// AMD
9249		//noinspection JSUnresolvedFunction
9250		define(factory);
9251	} else if (typeof exports === 'object') {
9252		// CommonJS
9253		module.exports = factory();
9254	} else {
9255		// Browser globals
9256		root.pickmeup = factory();
9257	}
9258}(this, function () {
9259	/**
9260	 * Functions prefixed with `dom_` are simple convenient wrappers for various operations with DOM
9261	 */
9262
9263	/**
9264	 * @param {(Element|NodeList)} element
9265	 * @param {Function}           callback
9266	 * @param {*}                  [args=[]]
9267	 */
9268	function dom_for_collection (element, callback, args) {
9269		args = args || [];
9270		if (element instanceof Element) {
9271			callback.apply(callback, [element].concat(args));
9272		} else {
9273			var elements, i;
9274			elements = element.length;
9275			for (i = 0; i < elements; ++i) {
9276				callback.apply(callback, [element[i]].concat(args));
9277			}
9278		}
9279	}
9280
9281	/**
9282	 * @param {(Element|Element[]|NodeList)} element
9283	 */
9284	function dom_remove (element) {
9285		dom_for_collection(element, function (element) {
9286			element.parentElement.removeChild(element);
9287		});
9288	}
9289
9290	/**
9291	 * @param {Element} element
9292	 * @param {string}  selector
9293	 *
9294	 * @returns {Element}
9295	 */
9296	function dom_closest_parent (element, selector) {
9297		var parent = element;
9298		do {
9299			parent = parent.parentElement;
9300		} while (parent && !dom_matches(parent, selector));
9301		return parent;
9302	}
9303
9304	/**
9305	 * @param {Element} element
9306	 * @param {string}  selector
9307	 *
9308	 * @returns {boolean}
9309	 */
9310	function dom_matches (element, selector) {
9311		return (element.matches || element.webkitMatchesSelector || element.msMatchesSelector).call(element, selector);
9312	}
9313
9314	/**
9315	 * @param {Element} element
9316	 * @param {string}  class_name
9317	 *
9318	 * @returns {boolean}
9319	 */
9320	function dom_has_class (element, class_name) {
9321		return element && element.classList.contains(class_name);
9322	}
9323
9324	/**
9325	 * @param {Element} element
9326	 * @param {string}  class_name
9327	 */
9328	function dom_add_class (element, class_name) {
9329		element.classList.add(class_name);
9330	}
9331
9332	/**
9333	 * @param {Element} element
9334	 * @param {string}  class_name
9335	 */
9336	function dom_remove_class (element, class_name) {
9337		element.classList.remove(class_name);
9338	}
9339
9340	/**
9341	 * @param {Element} element
9342	 * @param {string}  selector
9343	 *
9344	 * @returns {Element}
9345	 */
9346	function dom_query (element, selector) {
9347		return element.querySelector(selector);
9348	}
9349
9350	/**
9351	 * @param {Element} element
9352	 * @param {string}  selector
9353	 *
9354	 * @returns {Element[]}
9355	 */
9356	function dom_query_all (element, selector) {
9357		return Array.prototype.slice.call(element.querySelectorAll(selector));
9358	}
9359
9360	/**
9361	 * @param {Element}          target
9362	 * @param {(Element|Window)} element
9363	 * @param {string}           event
9364	 * @param {Function}         callback
9365	 */
9366	function dom_on (target, element, event, callback) {
9367		if (event.indexOf(' ') !== -1) {
9368			var events        = event.split(' '),
9369				events_number = events.length,
9370				i;
9371			for (i = 0; i < events_number; ++i) {
9372				dom_on(target, element, events[i], callback)
9373			}
9374		} else {
9375			target.__pickmeup.events.push([element, event, callback]);
9376			element.addEventListener(event, callback);
9377		}
9378	}
9379
9380	/**
9381	 * @param {Element}          target
9382	 * @param {(Element|Window)} [element=undefined]
9383	 * @param {string}           [event='']
9384	 * @param {Function}         [callback=undefined]
9385	 */
9386	function dom_off (target, element, event, callback) {
9387		var events,
9388			events_number,
9389			i;
9390		if (event && event.indexOf(' ') !== -1) {
9391			events        = event.split(' ');
9392			events_number = events.length;
9393			for (i = 0; i < events_number; ++i) {
9394				dom_off(target, element, events[i], callback)
9395			}
9396		} else {
9397			events        = target.__pickmeup.events;
9398			events_number = events.length;
9399			for (i = 0; i < events_number; ++i) {
9400				if (
9401					(element && element != events[i][0]) ||
9402					(event && event != events[i][1]) ||
9403					(callback && callback != events[i][2])
9404				) {
9405					continue;
9406				}
9407				events[i][0].removeEventListener(events[i][1], events[i][2]);
9408			}
9409		}
9410	}
9411
9412	/**
9413	 * @param {Element} element
9414	 *
9415	 * @returns {{top: number, left: number}}
9416	 */
9417	function dom_offset (element) {
9418		var rect = element.getBoundingClientRect();
9419		return {
9420			top  : rect.top + window.pageYOffset - document.documentElement.clientTop,
9421			left : rect.left + window.pageXOffset - document.documentElement.clientLeft
9422		};
9423	}
9424
9425	/**
9426	 * @param {Element} element
9427	 * @param {string}  event
9428	 * @param {Object}  [detail=undefined]
9429	 *
9430	 * @return {boolean}
9431	 */
9432	function dom_dispatch_event (element, event, detail) {
9433		var e = document.createEvent('Event');
9434		if (detail) {
9435			e.detail = detail;
9436		}
9437		e.initEvent('pickmeup-' + event, false, true);
9438		return element.dispatchEvent(e);
9439	}
9440
9441	/**
9442	 * Functions prefixed with `date_` are simple convenient wrappers for various operations with dates
9443	 */
9444
9445	/**
9446	 * @param {Date} date
9447	 *
9448	 * @returns {number}
9449	 */
9450	function date_get_max_days (date) {
9451		var tmpDate = new Date(date),
9452			d       = 28,
9453			m       = tmpDate.getMonth();
9454		while (tmpDate.getMonth() == m) {
9455			++d;
9456			tmpDate.setDate(d);
9457		}
9458		return d - 1;
9459	}
9460
9461	/**
9462	 * @param {Date}   date
9463	 * @param {number} number_of_days
9464	 */
9465	function date_add_days (date, number_of_days) {
9466		date.setDate(date.getDate() + number_of_days);
9467	}
9468
9469	/**
9470	 * @param {Date}   date
9471	 * @param {number} number_of_months
9472	 */
9473	function date_add_months (date, number_of_months) {
9474		var day = date.getDate();
9475		date.setDate(1);
9476		date.setMonth(date.getMonth() + number_of_months);
9477		date.setDate(Math.min(day, date_get_max_days(date)));
9478	}
9479
9480	/**
9481	 * @param {Date}   date
9482	 * @param {number} number_of_years
9483	 */
9484	function date_add_years (date, number_of_years) {
9485		var day = date.getDate();
9486		date.setDate(1);
9487		date.setFullYear(date.getFullYear() + number_of_years);
9488		date.setDate(Math.min(day, date_get_max_days(date)));
9489	}
9490
9491	/**
9492	 * @param {Date} date
9493	 *
9494	 * @returns {number}
9495	 */
9496	function date_get_day_of_the_year (date) {
9497		var now  = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
9498		var then = new Date(date.getFullYear(), 0, 0, 0, 0, 0);
9499		var time = now - then;
9500		return Math.floor(time / (24 * 60 * 60 * 1000));
9501	}
9502
9503	/**
9504	 * @param {Element} target
9505	 */
9506	function fill (target) {
9507		var root_element = target.__pickmeup.element,
9508			options      = target.__pickmeup.options,
9509			current_cal  = Math.floor(options.calendars / 2),
9510			actual_date  = options.date,
9511			current_date = options.current,
9512			min_date     = options.min ? new Date(options.min) : null,
9513			max_date     = options.max ? new Date(options.max) : null,
9514			local_date,
9515			header,
9516			instance,
9517			shown_date_from,
9518			shown_date_to,
9519			tmp_date;
9520		if (min_date) {
9521			min_date.setDate(1);
9522			date_add_months(min_date, 1);
9523			date_add_days(min_date, -1);
9524		}
9525		if (max_date) {
9526			max_date.setDate(1);
9527			date_add_months(max_date, 1);
9528			date_add_days(max_date, -1);
9529		}
9530		/**
9531		 * Remove old content except header navigation
9532		 */
9533		dom_remove(dom_query_all(root_element, '.pmu-instance > :not(nav)'));
9534		/**
9535		 * If several calendars should be shown
9536		 */
9537		for (var i = 0; i < options.calendars; i++) {
9538			local_date = new Date(current_date);
9539			reset_time(local_date);
9540			instance = dom_query_all(root_element, '.pmu-instance')[i];
9541			// if (dom_has_class(root_element, 'pmu-view-years')) {
9542			// 	date_add_years(local_date, (i - current_cal) * 12);
9543			// 	header = (local_date.getFullYear() - 6) + ' - ' + (local_date.getFullYear() + 5);
9544			// } else if (dom_has_class(root_element, 'pmu-view-months')) {
9545			// 	date_add_years(local_date, i - current_cal);
9546			// 	header = local_date.getFullYear();
9547			// } else if (dom_has_class(root_element, 'pmu-view-days')) {
9548			date_add_months(local_date, i - current_cal);
9549			header = format_date(local_date, options.title_format, options.locales[options.locale]);
9550			header2 = format_date(local_date, options.title_format2, options.locales[options.locale]);
9551			// }
9552			if (!shown_date_to) {
9553				if (max_date) {
9554					// If all dates in this month (months in year or years in years block) are after max option - set next month as current
9555					// in order not to show calendar with all disabled dates
9556					tmp_date = new Date(local_date);
9557					if (options.select_day) {
9558						date_add_months(tmp_date, options.calendars - 1);
9559					} else if (options.select_month) {
9560						date_add_years(tmp_date, options.calendars - 1);
9561					} else {
9562						date_add_years(tmp_date, (options.calendars - 1) * 12);
9563					}
9564					if (tmp_date > max_date) {
9565						--i;
9566						date_add_months(current_date, -1);
9567						shown_date_to = undefined;
9568						continue;
9569					}
9570				}
9571			}
9572			shown_date_to = new Date(local_date);
9573			if (!shown_date_from) {
9574				shown_date_from = new Date(local_date);
9575				// If all dates in this month are before min option - set next month as current in order not to show calendar with all disabled dates
9576				shown_date_from.setDate(1);
9577				date_add_months(shown_date_from, 1);
9578				date_add_days(shown_date_from, -1);
9579				if (min_date && min_date > shown_date_from) {
9580					--i;
9581					date_add_months(current_date, 1);
9582					shown_date_from = undefined;
9583					continue;
9584				}
9585			}
9586			dom_query(instance, '.pmu-month').innerHTML = header + ' <span>' + header2 + '</span>';
9587			var is_year_selected                          = function (year) {
9588				return (
9589						options.mode == 'range' &&
9590						year >
9590= new Date(actual_date[0]).getFullYear() &&
9591						year <= new Date(actual_date[1]).getFullYear()
9592					) ||
9593					(
9594						options.mode == 'multiple' &&
9595						actual_date.reduce(function (prev, current) {
9596							prev.push(new Date(current).getFullYear());
9597							return prev;
9598						}, []).indexOf(year) !== -1
9599					) ||
9600					new Date(actual_date).getFullYear() == year;
9601			};
9602			var is_months_selected                        = function (year, month) {
9603				var first_year  = new Date(actual_date[0]).getFullYear(),
9604					lastyear    = new Date(actual_date[1]).getFullYear(),
9605					first_month = new Date(actual_date[0]).getMonth(),
9606					last_month  = new Date(actual_date[1]).getMonth();
9607				return (
9608					(
9609						options.mode == 'range' &&
9610						(
9611							(year > first_year && year < lastyear) ||
9612							(year > first_year && year == lastyear && month <= last_month) ||
9613							(year == first_year && year < lastyear && month >= first_month) ||
9614							(year == first_year && year == lastyear && month >= first_month && month <= last_month)
9615						)
9616					) ||
9617					(
9618						options.mode == 'multiple' &&
9619						actual_date.reduce(function (prev, current) {
9620							current = new Date(current);
9621							prev.push(current.getFullYear() + '-' + current.getMonth());
9622							return prev;
9623						}, []).indexOf(year + '-' + month) !== -1
9624					) ||
9625					(
9626						new Date(actual_date).getFullYear() == year &&
9627						new Date(actual_date).getMonth() == month
9628					)
9629				);
9630			};
9631			// (function () {
9632			// 	var years_elements  = [],
9633			// 		start_from_year = local_date.getFullYear() - 6,
9634			// 		min_year        = new Date(options.min).getFullYear(),
9635			// 		max_year        = new Date(options.max).getFullYear(),
9636			// 		year,
9637			// 		year_element,
9638			// 		j;
9639			// 	for (j = 0; j < 12; ++j) {
9640			// 		year                         = start_from_year + j;
9641			// 		year_element                 = document.createElement('div');
9642			// 		year_element.textContent     = year;
9643			// 		year_element.__pickmeup_year = year;
9644			// 		if (
9645			// 			(options.min && year < min_year) ||
9646			// 			(options.max && year > max_year)
9647			// 		) {
9648			// 			dom_add_class(year_element, 'pmu-disabled');
9649			// 		} else if (is_year_selected(year)) {
9650			// 			dom_add_class(year_element, 'pmu-selected');
9651			// 		}
9652			// 		years_elements.push(year_element);
9653			// 	}
9654			// 	instance.appendChild(options.instance_content_template(years_elements, 'pmu-years'));
9655			// })();
9656			// (function () {
9657			// 	var months_elements = [],
9658			// 		current_year    = local_date.getFullYear(),
9659			// 		min_year        = new Date(options.min).getFullYear(),
9660			// 		min_month       = new Date(options.min).getMonth(),
9661			// 		max_year        = new Date(options.max).getFullYear(),
9662			// 		max_month       = new Date(options.max).getMonth(),
9663			// 		month,
9664			// 		month_element;
9665			// 	for (month = 0; month < 12; ++month) {
9666			// 		month_element                  = document.createElement('div');
9667			// 		month_element.textContent      = options.locales[options.locale].monthsShort[month];
9668			// 		month_element.__pickmeup_month = month;
9669			// 		month_element.__pickmeup_year  = current_year;
9670			// 		if (
9671			// 			(
9672			// 				options.min &&
9673			// 				(
9674			// 					current_year < min_year ||
9675			// 					(
9676			// 						month < min_month && current_year == min_year
9677			// 					)
9678			// 				)
9679			// 			) ||
9680			// 			(
9681			// 				options.max &&
9682			// 				(
9683			// 					current_year > max_year ||
9684			// 					(
9685			// 						month > max_month && current_year >= max_year
9686			// 					)
9687			// 				)
9688			// 			)
9689			// 		) {
9690			// 			dom_add_class(month_element, 'pmu-disabled');
9691			// 		} else if (is_months_selected(current_year, month)) {
9692			// 			dom_add_class(month_element, 'pmu-selected');
9693			// 		}
9694			// 		months_elements.push(month_element);
9695			// 	}
9696			// 	instance.appendChild(options.instance_content_template(months_elements, 'pmu-months'));
9697			// })();
9698			(function () {
9699				var days_elements = [],
9700					current_month = local_date.getMonth(),
9701					today         = reset_time(new Date).valueOf(),
9702					day,
9703					day_element,
9704					from_user,
9705					val,
9706					disabled,
9707					selected;
9708				// Correct first day in calendar taking into account the first day of the week (Sunday or Monday)
9709				(function () {
9710					local_date.setDate(1);
9711					var day = (local_date.getDay() - options.first_day) % 7;
9712					date_add_days(local_date, -(day + (day < 0 ? 7 : 0)));
9713				})();
9714				for (day = 0; day < 42; ++day) {
9715					day_element                  = document.createElement('div');
9716					day_element.textContent      = local_date.getDate();
9717					day_element.__pickmeup_day   = local_date.getDate();
9718					day_element.__pickmeup_month = local_date.getMonth();
9719					day_element.__pickmeup_year  = local_date.getFullYear();
9720					if (current_month != local_date.getMonth()) {
9721						dom_add_class(day_element, 'pmu-not-in-month');
9722					}
9723					if (local_date.getDay() == 0) {
9724						dom_add_class(day_element, 'pmu-sunday');
9725					} else if (local_date.getDay() == 6) {
9726						dom_add_class(day_element, 'pmu-saturday');
9727					}
9728					from_user = options.render(new Date(local_date)) || {};
9729					// We only reset time for this value in order to deal with Summer/Winter time, but changing `local_date` itself will break days incrementing
9730					val       = reset_time(new Date(local_date)).valueOf();
9731					disabled  =
9732						(options.min && options.min > local_date) ||
9733						(options.max && options.max < local_date);
9734					selected  =
9735						options.date.valueOf() == val ||
9736						(
9737							options.date instanceof Array &&
9738							options.date.reduce(function (prev, date) {
9739								return prev || val === date.valueOf();
9740							}, false)
9741						) ||
9742						(
9743							options.mode == 'range' && val >= options.date[0] && val <= options.date[1]
9744						);
9745					if (from_user.disabled || (!('disabled' in from_user) && disabled)) {
9746						dom_add_class(day_element, 'pmu-disabled');
9747					} else if (from_user.selected || (!('selected' in from_user) && selected)) {
9748						dom_add_class(day_element, 'pmu-selected');
9749						if (reset_time(new Date(local_date)).valueOf() == reset_time(new Date(options.date[0])).valueOf()) dom_add_class(day_element, 'pmu-selected-first');
9750						if (reset_time(new Date(local_date)).valueOf() == reset_time(new Date(options.date[1])).valueOf()) dom_add_class(day_element, 'pmu-selected-last');
9751					}
9752					if (val == today) {
9753						dom_add_class(day_element, 'pmu-today');
9754					}
9755					if (from_user.class_name) {
9756						from_user.class_name.split(' ').forEach(
9757							dom_add_class.bind(day_element, day_element)
9758						);
9759					}
9760					days_elements.push(day_element);
9761					// Move to the next day
9762					date_add_days(local_date, 1);
9763				}
9764				instance.appendChild(options.instance_content_template(days_elements, 'pmu-days'));
9765			})();
9766		}
9767		shown_date_from.setDate(1);
9768		shown_date_to.setDate(1);
9769		date_add_months(shown_date_to, 1);
9770		date_add_days(shown_date_to, -1);
9771		var prev = dom_query(root_element, '.pmu-prev'),
9772			next = dom_query(root_element, '.pmu-next');
9773		if (prev) {
9774			prev.style.visibility = options.min && options.min >= shown_date_from ? 'hidden' : 'visible';
9775		}
9776		if (next) {
9777			next.style.visibility = options.max && options.max <= shown_date_to ? 'hidden' : 'visible';
9778		}
9779		dom_dispatch_event(target, 'fill');
9780	}
9781
9782	function parse_date (date, options) {
9783		var format    = options.format,
9784			separator = options.separator,
9785			locale    = options.locales[options.locale],
9786			i;
9787		if (date instanceof Date || date instanceof Number) {
9788			return reset_time(new Date(date));
9789		} else if (!date) {
9790			return reset_time(new Date);
9791		} else if (date instanceof Array) {
9792			date = date.slice();
9793			for (i = 0; i < date.length; ++i) {
9794				date[i] = parse_date(date[i], options);
9795			}
9796			return date;
9797		}
9798		var splitted_date = date.split(separator);
9799		if (splitted_date.length > 1) {
9800			splitted_date.forEach(function (element, index, array) {
9801				array[index] = parse_date(element.trim(), options);
9802			});
9803			return splitted_date;
9804		}
9805		separator   = [].concat(locale.daysShort, locale.daysMin, locale.days, locale.monthsShort, locale.months);
9806		separator   = separator.map(function (item) {
9807			return '(' + item + ')';
9808		});
9809		separator   = new RegExp('[^0-9a-zA-Z' + separator.join('') + ']+');
9810		var parts   = date.split(separator),
9811			against = format.split(separator),
9812			d,
9813			m,
9814			y,
9815			h,
9816			min,
9817			now     = new Date();
9818		for (i = 0; i < parts.length; i++) {
9819			switch (against[i]) {
9820				case 'b':
9821					m = locale.monthsShort.indexOf(parts[i]);
9822					break;
9823				case 'B':
9824					m = locale.months.indexOf(parts[i]);
9825					break;
9826				case 'd':
9827				case 'e':
9828					d = parseInt(parts[i], 10);
9829					break;
9830				case 'm':
9831					m = parseInt(parts[i], 10) - 1;
9832					break;
9833				case 'Y':
9834				case 'y':
9835					y = parseInt(parts[i], 10);
9836					y += y > 100 ? 0 : (y < 29 ? 2000 : 1900);
9837					break;
9838				case 'H':
9839				case 'I':
9840				case 'k':
9841				case 'l':
9842					h = parseInt(parts[i], 10);
9843					break;
9844				case 'P':
9845				case 'p':
9846					if (/pm/i.test(parts[i]) && h < 12) {
9847						h += 12;
9848					} else if (/am/i.test(parts[i]) && h >= 12) {
9849						h -= 12;
9850					}
9851					break;
9852				case 'M':
9853					min = parseInt(parts[i], 10);
9854					break;
9855			}
9856		}
9857		var parsed_date = new Date(
9858			y === undefined ? now.getFullYear() : y,
9859			m === undefined ? now.getMonth() : m,
9860			d === undefined ? now.getDate() : d,
9861			h === undefined ? now.getHours() : h,
9862			min === undefined ? now.getMinutes() : min,
9863			0
9864		);
9865		if (isNaN(parsed_date * 1)) {
9866			parsed_date = new Date;
9867		}
9868		return reset_time(parsed_date);
9869	}
9870
9871	function reset_time (date) {
9872		date.setHours(0, 0, 0, 0);
9873		return date;
9874	}
9875
9876	function format_date (date, format, locale) {
9877		var m  = date.getMonth();
9878		var d  = date.getDate();
9879		var y  = date.getFullYear();
9880		var w  = date.getDay();
9881		var hr = date.getHours();
9882		var pm = (hr >= 12);
9883		var ir = (pm) ? (hr - 12) : hr;
9884		var dy = date_get_day_of_the_year(date);
9885		if (ir == 0) {
9886			ir = 12;
9887		}
9888		var min   = date.getMinutes();
9889		var sec   = date.getSeconds();
9890		var parts = format.split(''), part;
9891		for (var i = 0; i < parts.length; i++) {
9892			part = parts[i];
9893			switch (part) {
9894				case 'a':
9895					part = locale.daysShort[w];
9896					break;
9897				case 'A':
9898					part = locale.days[w];
9899					break;
9900				case 'b':
9901					part = locale.monthsShort[m];
9902					break;
9903				case 'B':
9904					part = locale.months[m];
9905					break;
9906				case 'C':
9907					part = 1 + Math.floor(y / 100);
9908					break;
9909				case 'd':
9910					part = (d < 10) ? ("0" + d) : d;
9911					break;
9912				case 'e':
9913					part = d;
9914					break;
9915				case 'H':
9916					part = (hr < 10) ? ("0" + hr) : hr;
9917					break;
9918				case 'I':
9919					part = (ir < 10) ? ("0" + ir) : ir;
9920					break;
9921				case 'j':
9922					part = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy;
9923					break;
9924				case 'k':
9925					part = hr;
9926					break;
9927				case 'l':
9928					part = ir;
9929					break;
9930				case 'm':
9931					part = (m < 9) ? ("0" + (1 + m)) : (1 + m);
9932					break;
9933				case 'M':
9934					part = (min < 10) ? ("0" + min) : min;
9935					break;
9936				case 'p':
9937				case 'P':
9938					part = pm ? "PM" : "AM";
9939					break;
9940				case 's':
9941					part = Math.floor(date.getTime() / 1000);
9942					break;
9943				case 'S':
9944					part = (sec < 10) ? ("0" + sec) : sec;
9945					break;
9946				case 'u':
9947					part = w + 1;
9948					break;
9949				case 'w':
9950					part = w;
9951					break;
9952				case 'y':
9953					part = ('' + y).substr(2, 2);
9954					break;
9955				case 'Y':
9956					part = y;
9957					break;
9958			}
9959			parts[i] = part;
9960		}
9961		return parts.join('');
9962	}
9963
9964	/**
9965	 * @param {Element} target
9966	 * @param {Date}    new_date
9967	 */
9968	function update_date (target, new_date) {
9969		var options = target.__pickmeup.options,
9970			i;
9971		reset_time(new_date);
9972		(function () {
9973			var new_value;
9974			switch (options.mode) {
9975				case 'multiple':
9976					new_value = new_date.valueOf();
9977					for (i = 0; i < options.date.length; ++i) {
9978						if (options.date[i].valueOf() === new_value) {
9979							options.date.splice(i, 1);
9980							return;
9981						}
9982					}
9983					options.date.push(new_date);
9984					break;
9985				case 'range':
9986					if (!options.lastSel) {
9987						options.date[0] = new_date;
9988					}
9989					if (new_date <= options.date[0]) {
9990						options.date[1] = options.date[0];
9991						options.date[0] = new_date;
9992					} else {
9993						options.date[1] = new_date;
9994					}
9995					options.lastSel = !options.lastSel;
9996					break;
9997				default:
9998					options.date = new_date.valueOf();
9999					break;
10000			}
10001		})();
10002		var prepared_date = prepare_date(options);
10003		if (dom_matches(target, 'input')) {
10004			//noinspection JSUndefinedPropertyAssignment
10005			target.value = options.mode == 'single' ? prepared_date.formatted_date : prepared_date.formatted_date.join(options.separator);
10006		}
10007		dom_dispatch_event(target, 'change', prepared_date);
10008		if (
10009			!options.flat &&
10010			options.hide_on_select &&
10011			(
10012				options.mode != 'range' || !options.lastSel
10013			)
10014		) {
10015			options.bound.hide();
10016		}
10017	}
10018
10019	/**
10020	 * @param {Element} target
10021	 * @param {Event}   event
10022	 *
10023	 * @returns {boolean}
10024	 */
10025	function click (target, event) {
10026		//noinspection JSValidateTypes
10027		/**
10028		 * @type {Element}
10029		 */
10030		var element = event.target;
10031		if (!dom_has_class(element, 'pmu-button')) {
10032			element = dom_closest_parent(element, '.pmu-button');
10033		}
10034		if (!dom_has_class(element, 'pmu-button') || dom_has_class(element, 'pmu-disabled')) {
10035			return false;
10036		}
10037		event.preventDefault();
10038		event.stopPropagation();
10039		var options        = target.__pickmeup.options,
10040			instance       = dom_closest_parent(element, '.pmu-instance'),
10041			root           = instance.parentElement,
10042			instance_index = dom_query_all(root, '.pmu-instance').indexOf(instance);
10043		if (dom_matches(element.parentElement, 'nav')) {
10044			if (dom_has_class(element, 'pmu-month')) {
10045				date_add_months(options.current, instance_index - Math.floor(options.calendars / 2));
10046				if (dom_has_class(root, 'pmu-view-years')) {
10047					// Shift back to current date, otherwise with min value specified may jump on few (tens) years forward
10048					if (options.mode != 'single') {
10049						options.current = new Date(options.date[options.date.length - 1]);
10050					} else {
10051						options.current = new Date(options.date);
10052					}
10053					if (options.select_day) {
10054						dom_remove_class(root, 'pmu-view-years');
10055						dom_add_class(root, 'pmu-view-days');
10056					} else if (options.select_month) {
10057						dom_remove_class(root, 'pmu-view-years');
10058						dom_add_class(root, 'pmu-view-months');
10059					}
10060				} else if (dom_has_class(root, 'pmu-view-months')) {
10061					if (options.select_year) {
10062						dom_remove_class(root, 'pmu-view-months');
10063						dom_add_class(root, 'pmu-view-years');
10064					} else if (options.select_day) {
10065						dom_remove_class(root, 'pmu-view-months');
10066						dom_add_class(root, 'pmu-view-days');
10067					}
10068				} else if (dom_has_class(root, 'pmu-view-days')) {
10069					if (options.select_month) {
10070						dom_remove_class(root, 'pmu-view-days');
10071						dom_add_class(root, 'pmu-view-months');
10072					} else if (options.select_year) {
10073						dom_remove_class(root, 'pmu-view-days');
10074						dom_add_class(root, 'pmu-view-years');
10075					}
10076				}
10077			} else {
10078				if (dom_has_class(element, 'pmu-prev')) {
10079					options.bound.prev(false);
10080				} else {
10081					options.bound.next(false);
10082				}
10083			}
10084		} else {
10085			if (dom_has_class(root, 'pmu-view-years')) {
10086				options.current.setFullYear(element.__pickmeup_year);
10087				if (options.select_month) {
10088					dom_remove_class(root, 'pmu-view-years');
10089					dom_add_class(root, 'pmu-view-months');
10090				} else if (options.select_day) {
10091					dom_remove_class(root, 'pmu-view-years');
10092					dom_add_class(root, 'pmu-view-days');
10093				} else {
10094					options.bound.update_date(options.current);
10095				}
10096			} else if (dom_has_class(root, 'pmu-view-months')) {
10097				options.current.setMonth(element.__pickmeup_month);
10098				options.current.setFullYear(element.__pickmeup_year);
10099				if (options.select_day) {
10100					dom_remove_class(root, 'pmu-view-months');
10101					dom_add_class(root, 'pmu-view-days');
10102				} else {
10103					options.bound.update_date(options.current);
10104				}
10105				// Move current month to the first place (needed for multiple calendars)
10106				date_add_months(options.current, Math.floor(options.calendars / 2) - instance_index);
10107			} else {
10108				var new_date = new Date(options.current);
10109				new_date.setYear(element.__pickmeup_year);
10110				new_date.setMonth(element.__pickmeup_month);
10111				new_date.setDate(element.__pickmeup_day);
10112				options.bound.update_date(new_date);
10113			}
10114		}
10115		options.bound.fill();
10116		return true;
10117	}
10118
10119	function prepare_date (options) {
10120		var result;
10121		if (options.mode == 'single') {
10122			result = new Date(options.date);
10123			return {
10124				formatted_date : format_date(result, options.format, options.locales[options.locale]),
10125				date           : result
10126			};
10127		} else {
10128			result = {
10129				formatted_date : [],
10130				date           : []
10131			};
10132			options.date.forEach(function (val) {
10133				var date = new Date(val);
10134				result.formatted_date.push(format_date(date, options.format, options.locales[options.locale]));
10135				result.date.push(date);
10136			});
10137			return result;
10138		}
10139	}
10140
10141	/**
10142	 * @param {Element} target
10143	 * @param {boolean} [force=false]
10144	 */
10145	function show (target, force) {
10146		var root_element = target.__pickmeup.element,
10147			value;
10148		if (force || dom_has_class(root_element, 'pmu-hidden')) {
10149			var options  = target.__pickmeup.options,
10150				position = dom_offset(target),
10151				viewport = {
10152					l : window.pageXOffset,
10153					t : window.pageYOffset,
10154					w : document.documentElement.clientWidth,
10155					h : document.documentElement.clientHeight
10156				},
10157				top      = position.top,
10158				left     = position.left;
10159			options.bound.fill();
10160			if (dom_matches(target, 'input')) {
10161				value = target.value;
10162				if (value) {
10163					options.bound.set_date(value);
10164				}
10165				dom_on(
10166					target,
10167					target,
10168					'keydown',
10169					function (e) {
10170						if (e.which == 9) {
10171							options.bound.hide();
10172						}
10173					}
10174				);
10175				options.lastSel = false;
10176			}
10177			if (!dom_dispatch_event(target, 'show')) {
10178				return;
10179			}
10180			if (!options.flat) {
10181				dom_remove_class(root_element, 'pmu-hidden');
10182				if (options.position instanceof Function) {
10183					position = options.position.call(target);
10184					left     = position.left;
10185					top      = position.top;
10186				} else {
10187					switch (options.position) {
10188						case 'top':
10189							top -= root_element.offsetHeight;
10190							break;
10191						case 'left':
10192							left -= root_element.offsetWidth;
10193							break;
10194						case 'right':
10195							left += target.offsetWidth;
10196							break;
10197						case 'bottom':
10198							top += target.offsetHeight;
10199							break;
10200					}
10201					if (top + root_element.offsetHeight > viewport.t + viewport.h) {
10202						top = position.top - root_element.offsetHeight;
10203					}
10204					if (top < viewport.t) {
10205						top = position.top + target.offsetHeight;
10206					}
10207					if (left + root_element.offsetWidth > viewport.l + viewport.w) {
10208						left = position.left - root_element.offsetWidth;
10209					}
10210					if (left < viewport.l) {
10211						left = position.left + target.offsetWidth;
10212					}
10213					left += 'px';
10214					top += 'px';
10215				}
10216				root_element.style.left = left;
10217				root_element.style.top  = top;
10218				setTimeout(function () {
10219					dom_on(target, document.documentElement, 'click', options.bound.hide);
10220					dom_on(target, window, 'resize', options.bound.forced_show);
10221				});
10222			}
10223		}
10224	}
10225
10226	/**
10227	 * @param {Element} target
10228	 * @param {Event}   event
10229	 */
10230	function hide (target, event) {
10231		var root_element = target.__pickmeup.element,
10232			options      = target.__pickmeup.options;
10233		//noinspection JSBitwiseOperatorUsage,JSCheckFunctionSignatures
10234		if (
10235			!event || !event.target ||										//Called directly
10236			(
10237				event.target != target &&									//Clicked not on element itself
10238				!(root_element.compareDocumentPosition(event.target) & 16)	//And not on its children
10239			)
10240		) {
10241			if (dom_dispatch_event(target, 'hide')) {
10242				dom_add_class(root_element, 'pmu-hidden');
10243				dom_off(target, document.documentElement, 'click', options.bound.hide);
10244				dom_off(target, window, 'resize', options.bound.forced_show);
10245				options.lastSel = false;
10246			}
10247		}
10248	}
10249
10250	/**
10251	 * @param {Element} target
10252	 */
10253	function update (target) {
10254		var options = target.__pickmeup.options;
10255		dom_off(target, document.documentElement, 'click', options.bound.hide);
10256		dom_off(target, window, 'resize', options.bound.forced_show);
10257		options.bound.forced_show();
10258	}
10259
10260	/**
10261	 * @param {Element} target
10262	 */
10263	function clear (target) {
10264		var options = target.__pickmeup.options;
10265		if (options.mode != 'single') {
10266			options.date    = [];
10267			options.lastSel = false;
10268			options.bound.fill();
10269		}
10270	}
10271
10272	/**
10273	 * @param {Element} target
10274	 * @param {boolean} [fill=true]
10275	 */
10276	function prev (target, fill) {
10277		if (typeof fill == 'undefined') {
10278			fill = true;
10279		}
10280		var root_element = target.__pickmeup.element;
10281		var options      = target.__pickmeup.options;
10282		if (dom_has_class(root_element, 'pmu-view-years')) {
10283			date_add_years(options.current, -12);
10284		} else if (dom_has_class(root_element, 'pmu-view-months')) {
10285			date_add_years(options.current, -1);
10286		} else if (dom_has_class(root_element, 'pmu-view-days')) {
10287			date_add_months(options.current, -1);
10288		}
10289		if (fill) {
10290			options.bound.fill();
10291		}
10292	}
10293
10294	/**
10295	 * @param {Element} target
10296	 * @param {boolean} [fill=true]
10297	 */
10298	function next (target, fill) {
10299		if (typeof fill == 'undefined') {
10300			fill = true;
10301		}
10302		var root_element = target.__pickmeup.element;
10303		var options      = target.__pickmeup.options;
10304		if (dom_has_class(root_element, 'pmu-view-years')) {
10305			date_add_years(options.current, 12);
10306		} else if (dom_has_class(root_element, 'pmu-view-months')) {
10307			date_add_years(options.current, 1);
10308		} else if (dom_has_class(root_element, 'pmu-view-days')) {
10309			date_add_months(options.current, 1);
10310		}
10311		if (fill) {
10312			options.bound.fill();
10313		}
10314	}
10315
10316	/**
10317	 * @param {Element} target
10318	 * @param {boolean} [formatted=true]
10319	 */
10320	function get_date (target, formatted) {
10321		var options       = target.__pickmeup.options,
10322			prepared_date = prepare_date(options);
10323		if (typeof formatted === 'string') {
10324			var date = prepared_date.date;
10325			if (date instanceof Date) {
10326				return format_date(date, formatted, options.locales[options.locale])
10327			} else {
10328				return date.map(function (value) {
10329					return format_date(value, formatted, options.locales[options.locale]);
10330				});
10331			}
10332		} else {
10333			return prepared_date[formatted ? 'formatted_date' : 'date'];
10334		}
10335	}
10336
10337	/**
10338	 * @param {Element}                                       target
10339	 * @param {(Date|Date[]|number|number[]|string|string[])} date
10340	 * @param {Date}                                          [current=undefined]
10341	 */
10342	function set_date (target, date, current) {
10343		var options = target.__pickmeup.options,
10344			i;
10345		if (!(date instanceof Array) || date.length > 0) {
10346			options.date = parse_date(date, options);
10347			if (options.mode != 'single') {
10348				if (options.date instanceof Array) {
10349					options.date[0] = options.date[0] || parse_date(new Date, options);
10350					if (options.mode == 'range') {
10351						options.date[1] = options.date[1] || parse_date(options.date[0], options);
10352					}
10353				} else {
10354					options.date = [options.date];
10355					if (options.mode == 'range') {
10356						options.date.push(parse_date(options.date[0], options));
10357					}
10358				}
10359				for (i = 0; i < options.date.length; ++i) {
10360					options.date[i] = correct_date_outside_of_limit(options.date[i], options.min, options.max);
10361				}
10362			} else {
10363				if (options.date instanceof Array) {
10364					options.date = options.date[0];
10365				}
10366				options.date = correct_date_outside_of_limit(options.date, options.min, options.max);
10367			}
10368		} else {
10369			options.date = [];
10370		}
10371		if (!options.select_day) {
10372			if (options.date instanceof Array) {
10373				for (i = 0; i < options.date.length; ++i) {
10374					options.date[i].setDate(1);
10375				}
10376			} else {
10377				options.date.setDate(1);
10378			}
10379		}
10380		// Remove duplicates
10381		if (options.mode == 'multiple') {
10382			for (i = 0; i < options.date.length; ++i) {
10383				if (options.date.indexOf(options.date[i]) !== i) {
10384					options.date.splice(i, 1);
10385					--i;
10386				}
10387			}
10388		}
10389		if (current) {
10390			options.current = parse_date(current, options);
10391		} else {
10392			current         = options.mode === 'single' ? options.date : options.date[options.date.length - 1];
10393			options.current = current ? new Date(current) : new Date;
10394		}
10395		options.current.setDate(1);
10396		options.bound.fill();
10397		if (dom_matches(target, 'input') && options.default_date !== false) {
10398			var prepared_date = prepare_date(options),
10399				current_value = target.value,
10400				new_value     = options.mode == 'single' ? prepared_date.formatted_date : prepared_date.formatted_date.join(options.separator);
10401			if (!current_value) {
10402				dom_dispatch_event(target, 'change', prepared_date);
10403			}
10404			if (current_value != new_value) {
10405				//noinspection JSUndefinedPropertyAssignment
10406				target.value = new_value;
10407			}
10408		}
10409	}
10410
10411	/**
10412	 * @param {Element} target
10413	 */
10414	function destroy (target) {
10415		var root_element = target.__pickmeup.element;
10416		dom_off(target);
10417		dom_remove(root_element);
10418		delete target.__pickmeup;
10419	}
10420
10421	function correct_date_outside_of_limit (date, min, max) {
10422		if (min && min > date) {
10423			return new Date(min);
10424		} else if (max && max < date) {
10425			return new Date(max);
10426		}
10427		return date;
10428	}
10429
10430	/**
10431	 * @param {(Element|string)} target
10432	 * @param {Object}           [initial_options={}]
10433	 *
10434	 * @return {(Object|null)} Object with useful methods on success, `null` otherwise
10435	 */
10436	function pickmeup_init (target, initial_options) {
10437		if (typeof target == 'string') {
10438			target = document.querySelector(target);
10439		}
10440		if (!target) {
10441			return null;
10442		}
10443		if (!target.__pickmeup) {
10444			var i,
10445				option,
10446				options     = {};
10447			initial_options = initial_options || {};
10448			for (i in pickmeup_init.defaults) {
10449				options[i] = i in initial_options ? initial_options[i] : pickmeup_init.defaults[i];
10450			}
10451			for (i in options) {
10452				option = target.getAttribute('data-pmu-' + i);
10453				if (option !== null) {
10454					options[i] = option;
10455				}
10456			}
10457			// 4 conditional statements in order to account all cases
10458			if (options.view == 'days' && !options.select_day) {
10459				options.view = 'months';
10460			}
10461			if (options.view == 'months' && !options.select_month) {
10462				options.view = 'years';
10463			}
10464			if (options.view == 'years' && !options.select_year) {
10465				options.view = 'days';
10466			}
10467			if (options.view == 'days' && !options.select_day) {
10468				options.view = 'months';
10469			}
10470			options.calendars = Math.max(1, parseInt(options.calendars, 10) || 1);
10471			options.mode      = /single|multiple|range/.test(options.mode) ? options.mode : 'single';
10472			if (options.min) {
10473				options.min = parse_date(options.min, options);
10474				if (!options.select_day) {
10475					options.min.setDate(1);
10476				}
10477			}
10478			if (options.max) {
10479				options.max = parse_date(options.max, options);
10480				if (!options.select_day) {
10481					options.max.setDate(1);
10482				}
10483			}
10484			var element               = document.createElement('div');
10485			//noinspection JSUndefinedPropertyAssignment
10486			target.__pickmeup         = {
10487				options : options,
10488				events  : [],
10489				element : element
10490			};
10491			element.__pickmeup_target = target;
10492			dom_add_class(element, 'pickmeup');
10493			if (options.class_name) {
10494				dom_add_class(element, options.class_name);
10495			}
10496			options.bound = {
10497				fill        : fill.bind(target, target),
10498				update_date : update_date.bind(target, target),
10499				click       : click.bind(target, target),
10500				show        : show.bind(target, target),
10501				forced_show : show.bind(target, target, true),
10502				hide        : hide.bind(target, target),
10503				update      : update.bind(target, target),
10504				clear       : clear.bind(target, target),
10505				prev        : prev.bind(target, target),
10506				next        : next.bind(target, target),
10507				get_date    : get_date.bind(target, target),
10508				set_date    : set_date.bind(target, target),
10509				destroy     : destroy.bind(target, target)
10510			};
10511			dom_add_class(element, 'pmu-view-' + options.view);
10512			var content_template = options.instance_template(options),
10513				content          = '';
10514			for (i = 0; i < options.calendars; ++i) {
10515				content += content_template;
10516			}
10517			element.innerHTML = content;
10518			dom_on(target, element, 'click', options.bound.click);
10519			dom_on(
10520				target,
10521				element,
10522				'onselectstart' in Element.prototype ? 'selectstart' : 'mousedown',
10523				function (e) {
10524					e.preventDefault();
10525				});
10526			if (options.flat) {
10527				dom_add_class(element, 'pmu-flat');
10528				target.appendChild(element);
10529			} else {
10530				dom_add_class(element, 'pmu-hidden');
10531				document.body.appendChild(element);
10532				dom_on(target, target, 'click', show.bind(target, target, false));
10533				dom_on(target, target, 'input', options.bound.update);
10534				dom_on(target, target, 'change', options.bound.update);
10535			}
10536			options.bound.set_date(options.date, options.current);
10537		}
10538		options = target.__pickmeup.options;
10539		return {
10540			hide     : options.bound.hide,
10541			show     : options.bound.show,
10542			clear    : options.bound.clear,
10543			update   : options.bound.update,
10544			prev     : options.bound.prev,
10545			next     : options.bound.next,
10546			get_date : options.bound.get_date,
10547			set_date : options.bound.set_date,
10548			destroy  : options.bound.destroy
10549		}
10550	}
10551
10552	pickmeup_init.defaults = {
10553		current                   : null,
10554		date                      : new Date,
10555		default_date              : new Date,
10556		flat                      : false,
10557		first_day                 : 1,
10558		prev                      : '&#9664;',
10559		next                      : '&#9654;',
10560		mode                      : 'single',
10561		select_year               : false,
10562		select_month              : false,
10563		select_day                : true,
10564		view                      : 'days',
10565		calendars                 : 1,
10566		format                    : 'd-m-Y',
10567		title_format              : 'B',
10568		title_format2              : 'Y',
10569		position                  : 'bottom',
10570		class_name                : '',
10571		separator                 : ' - ',
10572		hide_on_select            : false,
10573		min                       : null,
10574		max                       : null,
10575		render                    : function () {
10576		},
10577		locale                    : 'en',
10578		locales                   : {
10579			en: {
10580				days        : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
10581				daysShort   : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
10582				daysMin     : ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
10583				months      : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
10584				monthsShort : ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
10585			},
10586			int: {
10587				days        : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
10588				daysShort   : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
10589				daysMin     : ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
10590				months      : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
10591				monthsShort : ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
10592			},
10593			ru: {
10594				daysMin: [],
10595				months: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
10596				monthsShort: []
10597			},
10598			de: {
10599				daysMin: [],
10600				months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
10601				monthsShort: []
10602			},
10603			es: {
10604				daysMin: [],
10605				months: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', '
10605Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
10606				monthsShort: []
10607			},
10608			uz: {
10609				daysMin: [],
10610				months: ['Январ', 'Феврал', 'Март', 'Апрел', 'Май', 'Июн', 'Июл', 'Август', 'Сентябр', 'Октябр', 'Ноябр', 'Декабр'],
10611				monthsShort: []
10612			},
10613			gr: {
10614				daysMin: [],
10615				months: ['Ιανουάριος', 'Φεβρουάριος', 'Μάρτιος', 'Απρίλιος', 'Μάιος', 'Ιούνιος', 'Ιούλιος', 'Αύγουστος', 'Σεπτέμβριος', 'Οκτώβριος', 'Νοέμβριος', 'Δεκέμβριος'],
10616				monthsShort: []
10617			},
10618			tj: {
10619				daysMin: [],
10620				months: ['Январ', 'Феврал', 'Март', 'Апрел', 'Май', 'Июн', 'Июл', 'Август', 'Сентябр', 'Октябр', 'Ноябр', 'Декабр'],
10621				monthsShort: []
10622			},
10623			tg: {
10624				daysMin: [],
10625				months: ['Январ', 'Феврал', 'Март', 'Апрел', 'Май', 'Июн', 'Июл', 'Август', 'Сентябр', 'Октябр', 'Ноябр', 'Декабр'],
10626				monthsShort: []
10627			},
10628			cz: {
10629				daysMin: [],
10630				months: ['Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec'],
10631				monthsShort: []
10632			},
10633			cs: {
10634				daysMin: [],
10635				months: ['Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec'],
10636				monthsShort: []
10637			},
10638			lt:{
10639				daysMin: [],
10640				months: ['Sausis', 'Vasaris', 'Kovas', 'Balandis', 'Gegužė', 'Birželis', 'Liepa', 'Rugpjūtis', 'Rugsėjis', 'Spalis', 'Lapkritis', 'Gruodis'],
10641				monthsShort: []
10642			},
10643			lv:{
10644				daysMin: [],
10645				months: ['Janvāris', 'Februāris', 'Marts', 'Aprīlis', 'Maijs', 'Jūnijs', 'Jūlijs', 'Augusts', 'Septembris', 'Oktobris', 'Novembris', 'Decembris'],
10646				monthsShort: []
10647			},
10648			it:{
10649				daysMin: [],
10650				months: ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre'],
10651				monthsShort: []
10652			},
10653			pl:{
10654				daysMin: [],
10655				months: ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień'],
10656				monthsShort: []
10657			},
10658			by:{
10659				daysMin: [],
10660				months: ['Студзень', 'Люты', 'Сакавік', 'Красавік', 'Май', 'Чэрвень', 'Ліпень', 'Жнівень', 'Верасень', 'Кастрычнік', 'Лістапад', 'Снежань'],
10661				monthsShort: []
10662			},
10663			rs:{
10664				daysMin: [],
10665				months: ['Јануар', 'Фебруар', 'Март', 'Април', 'Мај', 'Јун', 'Јул', 'Август', 'Септембар', 'Октобар', 'Новембар', 'Децембар'],
10666				monthsShort: []
10667			},
10668			md:{
10669				daysMin: [],
10670				months: ['Ianuarie', 'Februarie', 'Martie', 'Aprilie', 'Mai', 'Iunie', 'Iulie', 'August', 'Septembrie', 'Octombrie', 'Noiembrie', 'Decembrie'],
10671				monthsShort: []
10672			},
10673			tr:{
10674				daysMin: [],
10675				months: ['Ocak', 'Şubat', 'Mart', 'Nisan', 'Mayıs', 'Haziran', 'Temmuz', 'Ağustos', 'Eylül', 'Ekim', 'Kasım', 'Aralık'],
10676				monthsShort: []
10677			},
10678			ge:{
10679				daysMin: [],
10680				months: ['იანვარი', 'თებერვალი', 'მარტი', 'აპრილი', 'მაისი', 'ივნისი', 'ივლისი', 'აგვისტო', 'სექტემბერი', 'ოქტომბერი', 'ნოემბერი', 'დეკემბერი'],
10681				monthsShort: []
10682			},
10683			am:{
10684				daysMin: [],
10685				months: ['Հունվար', 'Փետրվար', 'Մարտ', 'Ապրիլ', 'Մայիս', 'Հունիս', 'Հուլիս', 'Օգոստոս', 'Սեպտեմբեր', 'Հոկտեմբեր', 'Նոյեմբեր', 'Դեկտեմբեր'],
10686				monthsShort: []
10687			},
10688			fr:{
10689				daysMin: [],
10690				months: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
10691				monthsShort: []
10692			},
10693			az:{
10694				daysMin: [],
10695				months: ['Yanvar', 'Fevral', 'Mart', 'Aprel', 'May', 'İyun', 'İyul', 'Avqust', 'Sentyabr', 'Oktyabr', 'Noyabr', 'Dekabr'],
10696				monthsShort: []
10697			},
10698			vn:{
10699				daysMin: [],
10700				months: ['Tháng Một', 'Tháng Hai', 'Tháng Ba', 'Tháng Tư', 'Tháng Năm', 'Tháng Sáu', 'Tháng Bảy', 'Tháng Tám', 'Tháng Chín', 'Tháng Mười', 'Tháng Mười Một', 'Tháng Mười Hai'],
10701				monthsShort: []
10702			},
10703			ab:{
10704				daysMin: [],
10705				months: ['Ажьырныҳәа', 'Жәабран', 'Хәыжәкыра', 'Мшаԥы', 'Лаҵара', 'Рашәара', 'Ԥхынгәы', 'Нанҳәа', 'Цәыбббра', 'Жьҭаара', 'Абҵара', 'Ԥхынҷкәын'],
10706				monthsShort: []
10707			},
10708			jp:{
10709				daysMin: [],
10710				months: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
10711				monthsShort: []
10712			},
10713			eg:{
10714				daysMin: [],
10715				months: ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'],
10716				monthsShort: []
10717			},
10718			os: {
10719				daysMin: [],
10720				months: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
10721				monthsShort: []
10722			},
10723			br: {
10724				daysMin: [],
10725				months: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', '
10725Setembro', 'Outubro', 'Novembro', 'Dezembro'],
10726				monthsShort: []
10727			},
10728			da: {
10729				daysMin: [],
10730				months: ['جنوری', 'فبروری', 'مارچ', 'اپریل', 'می', 'جون', 'جولای', 'اگست', 'سپتمبر', 'اکتوبر', 'نوامبر', 'دسمبر'],
10731				monthsShort: []
10732			},
10733			fa: {
10734				daysMin: [],
10735				months: ['ژانویه', 'فوریه', 'مارس', 'آوریل', 'مه', 'ژوئن', 'ژوئیه', 'اوت', 'سپتامبر', 'اکتبر', 'نوامبر', 'دسامبر'],
10736				monthsShort: []
10737			},
10738			kg: {
10739				daysMin: [],
10740				months: ['Үчтүн айы', 'Бирдин айы', 'Жалган Куран', 'Чын Куран', 'Бугу', 'Кулжа', 'Теке', 'Баш оона', 'Аяк оона', 'Тогуздун айы', 'Жетинин айы', 'Бештин айы'],
10741				monthsShort: []
10742			},
10743			cn: {
10744				daysMin: [],
10745				months: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
10746				monthsShort: []
10747			},
10748			kz: {
10749				daysMin: [],
10750				months: ['Қаңтар', 'Ақпан', 'Наурыз', 'Сәуір', 'Мамыр', 'Маусым', 'Шілде', 'Тамыз', 'Қыркүйек', 'Қазан', 'Қараша', 'Желтоқсан'],
10751				monthsShort: []
10752			},
10753			kaz: {
10754				daysMin: [],
10755				months: ['Қаңтар', 'Ақпан', 'Наурыз', 'Сәуір', 'Мамыр', 'Маусым', 'Шілде', 'Тамыз', 'Қыркүйек', 'Қазан', 'Қараша', 'Желтоқсан'],
10756				monthsShort: []
10757			},
10758			mn: {
10759				daysMin: [],
10760				months: ['Нэгдүгээр сар', 'Хоёрдугаар сар', 'Гуравдугаар сар', 'Дөрөвдүгээр сар', 'Тавдугаар сар', 'Зургаадугаар сар', 'Долоодугаар сар', 'Наймдугаар сар', 'Есдүгээр сар', 'Аравдугаар сар', 'Арваннэгдүгээр сар', 'Арванхоёрдугаар сар'],
10761				monthsShort: []
10762			},
10763			in: {
10764				days        : ['रविवार ', 'सोमवार ', 'मंगलवार ', 'बुधवार ', 'गुरुवार ', 'शुक्रवार', 'शनिवार '],
10765				daysShort   : ['र ', 'सो ', 'मं ', 'बु ', 'गु ', 'शु ', 'श '],
10766				daysMin     : ['र ', 'सो ', 'मं ', 'बु ', 'गु ', 'शु ', 'श '],
10767				months      : ['जनवरी', 'फ़रवरी ', 'मार्च ', 'अप्रैल ', 'मई ', 'जून ', 'जुलाई  ', 'अगस्त ', 'सितंबर ', 'अक्टूबर', 'नवंबर ', 'दिसंबर '],
10768				monthsShort : ['जनवरी', 'फ़रवरी ', 'मार्च ', 'अप्रैल ', 'मई ', 'जून ', 'जुलाई  ', 'अगस्त ', 'सितंबर ', 'अक्टूबर', 'नवंबर ', 'दिसंबर ']
10769			}
10770		},
10771		/**
10772		 * @param {Object} options
10773		 *
10774		 * @returns {string}
10775		 */
10776		instance_template         : function (options) {
10777			// var days_of_week = options.locales[options.locale].daysMin.slice();
10778			// // If Monday is the first day of the week
10779			// if (options.first_day) {
10780			// 	days_of_week.push(days_of_week.shift());
10781			// }
10782			// return '<div class="pmu-instance">' +
10783			// 	'<nav>' +
10784			// 	'<div class="pmu-prev pmu-button">' + options.prev + '</div>' +
10785			// 	'<div class="pmu-month pmu-button"></div>' +
10786			// 	'<div class="pmu-next pmu-button">' + options.next + '</div>' +
10787			// 	'</nav>' +
10788			// 	'<nav class="pmu-day-of-week"><div>' + days_of_week.join('</div><div>') + '</div></nav>' +
10789			// 	'</div>';
10790			return '<div class="pmu-instance">' +
10791				'<nav>' +
10792				'<div class="pmu-month"><span></span></div>' +
10793				'</nav>' +
10794				'</div>';
10795		},
10796		/**
10797		 * @param {Element[]} elements
10798		 * @param {string}
10798    container_class_name
10799		 *
10800		 * @returns {Element}
10801		 */
10802		instance_content_template : function (elements, container_class_name) {
10803			var root_element = document.createElement('div');
10804			dom_add_class(root_element, container_class_name);
10805			for (var i = 0; i < elements.length; ++i) {
10806				dom_add_class(elements[i], 'pmu-button');
10807				root_element.appendChild(elements[i]);
10808			}
10809			return root_element;
10810		}
10811	};
10812
10813	return pickmeup_init;
10814}));
10815
10816
10817(function($){
10818
10819	$.fn.riaForm = function(options){
10820
10821		var version = "1.5";
10822
10823		/* НАСТРОЙКИ */
10824
10825		var options = $.extend({
10826			type: 'post',                       // для ajax, тип выполняемого запроса
10827			dataType: 'json',                   // тип данных, в котором ожидается получить ответ от сервера
10828			block: true,                        // блокировать форму при ajax запросе
10829			loader: '.loader',                  // селектор лоадера, должен находиться в <form>...</form>
10830			deleteData: false,                  // object - поля которые надо удалить из отправки
10831			rules: false,                       // object - правила для обязательных к заполнению полей
10832			mixinData: false,                   // function - добавление полей
10833			/*
10834			*           Настройки добавления классов ошибок на поля и label
10835			*/
10836			errorClass: 'm-error',              // класс ошибки, добавляется на элемент и/или label (класс без точки)
10837			errorInput: false,                  // добавлять класс ошибки на элемент
10838			errorLabel: false,                  // добавлять класс ошибки на label
10839			/*
10840			*			Настройки вывода ошибок полей
10841			*		    <form> ... <span class="message-error" data-field="field_name"></span> ... </form>
10842			*/
10843			errorMessage: true,                 // показывать сообщение об ошибке
10844			message: '.message-error',          // селектор блока для вывода сообщения об ошибке
10845			messageConnector: 'data-field',     // атрибут поля в которое выводится сообщение об ошибке, равен имени поля для которого выводится сообщение
10846			messages: false,                    // object - сообщения об ошибках для обязательных к заполнению полей
10847			errorCallback: undefined,           // function - вызывается при налиции ошибок в заполнении формы (обязательных полей определенных в rules) принимает массив ошибок
10848			/*
10849			*           Настройки вывода алертов полей
10850			*           <form> ... <div class="message-alert"></div> ... </form>
10851			*/
10852			errorAlert: false,                  // показывать алерт пришедший в ответ
10853			alert: '.message-alert',            // селектор блока для вывода алерта
10854			alerts: false,                      // object - алерты
10855			alertCallback: undefined,           // function - вызываетя после показа алерта
10856			/*
10857			*           callback функции
10858			*/
10859			submitCallback: undefined,          // function - выполняется перед отправкой данных
10860			successCallback: undefined,         // function - выполняется при возврате ответа success
10861			forceCallback: undefined            // function - выполняется при любом ответе
10862
10863		}, options || {});
10864
10865		/* ПЕРЕМЕННЫЕ */
10866
10867		var form = $(this);                     // <form> - вещать плагин на него
10868		var loader = $(options.loader, form);   // лоадер
10869		var dataUrl = form.attr('action');      // url для ajax, берет с атрибута action form
10870		var errors = 0;
10871		var errorsMessage = {};
10872
10873		/* ФУНКЦИИ  */
10874
10875		/* Показывает ошибку */
10876		var showFieldError = function(name, error){
10877			/* показывает пару "поле ошибка" в консоли */
10878			console.log(name,'  ', error);
10879			/* Останавливается если не переданы параметры */
10880			if(!name || !error){
10881				return;
10882			}
10883			var field;
10884			/* Проверка какое поле имеет переданный name и сохранение в field */
10885			if($('input[name="' + name + '"]', form).length > 0){
10886				field = $('input[name="' + name + '"]', form);
10887			} else if($('textarea[name="' + name + '"]', form).length > 0){
10888				field = $('textarea[name="' + name + '"]', form);
10889			} else if($('select[name="' + name + '"]', form).length > 0){
10890				field = $('select[name="' + name + '"]', form);
10891			} else {
10892				return;
10893			}
10894			/* Добавляет класс ошибки тегу input, textarea или select */
10895			if(options.errorInput){
10896				field.addClass(options.errorClass);
10897			}
10898			/* Добавляет класс ошибки к лейблу поля */
10899			if(options.errorLabel){
10900				var label = $('label[for="'+ field.attr('id') +'"]');
10901				if(label.length > 0){
10902					/* Добавляетк ласс ошибки на label[for="..."]*/
10903					label.addClass(options.errorClass);
10904				} else if(field.parent().get(0) && field.parent().get(0).tagName == 'LABEL'){
10905					/* Добавляет класс ошибки на первый родительский label */
10906					field.parent().addClass(options.errorClass);
10907				}
10908			}
10909			/* Показывает сообщение об ошибке для поля */
10910			if(options.errorMessage){
10911				var message = $(options.message + '[' + options.messageConnector + '="' + name + '"]', form);
10912				if(message.length > 0 && options.messages && options.messages[name]){
10913					message.empty().append(options.messages[name][error]).show();
10914				}
10915			}
10916		};
10917
10918		/* Проверка правил и подсветка ошибок */
10919		var checkRules = function(){
10920			for(key in options.rules){
10921				var type = $.type(options.rules[key]);
10922				/* Если передан объект */
10923				if(type === 'object'){
10924					for(node in options.rules[key]){
10925						var name = key;
10926						var value = options.rules[key][node];
10927						checkRulesType(name, node, value);
10928					}
10929				}
10930				/* Если передан массив */
10931				if(type === 'array'){
10932					var name = key;
10933					for(node in options.rules[key]){
10934						value = options.rules[key][node];
10935						checkRulesType(name, value);
10936					}
10937				}
10938				/* Проверяет переданное значение */
10939				else{
10940					checkRulesType(key, options.rules[key]);
10941				}
10942			}
10943
10944			return errors;
10945
10946		};
10947
10948		var checkRulesType = function(name, key, value){
10949			switch(key){
10950
10951				/* Функция */
10952				case 'function':
10953					if(value instanceof Function){
10954						var result = value(form,name);
10955						if(result == false){
10956							errors++;
10957							errorsMessage[name] = 'function';
10958							showFieldError(name, 'function');
10959						}
10960					}
10961					break;
10962
10963				/* Пустрое поле */
10964				case 'empty':
10965					var empty = checkFieldEmpty(name);
10966					if(empty == true){
10967						errors++;
10968						errorsMessage[name] = 'empty';
10969					}
10970					break;
10971
10972				/* Email */
10973				case 'email':
10974					var email = checkFieldEmail(name);
10975					if(email == true){
10976						errors++;
10977						errorsMessage[name] = 'email';
10978					}
10979					break;
10980
10981				case 'number':
10982					var number = checkFieldNumber(name);
10983					if(number == true){
10984						errors++;
10985						errorsMessage[name] = 'number';
10986					}
10987					break;
10988			}
10989			/* Отдельная проверка переданного объекта*/
10990			if(key instanceof Function){
10991				var result = key(form,name);
10992				if(result == false){
10993					errors++;
10994					errorsMessage[name] = 'function';
10995					showFieldError(name, 'function');
10996				}
10997			}
10998		};
10999
11000		/* Проверяет пустые поля */
11001		var checkFieldEmpty = function(name){
11002
11003			/* Для input тип checkbox и radio */
11004			if($('input[name="'+ name +'"][type="checkbox"], input[name="'+ name +'"][type="radio"]', form).length > 0){
11005				var value = $('input[name="'+ name +'"]', form).is(':checked');
11006				if(value == false){
11007					showFieldError(name, 'empty');
11008					return true;
11009				}
11010			}
11011
11012			/* Для input тип file */
11013			if($('input[name="'+ name +'"][type="file"]', form).length > 0){
11014				var file_api = ( window.File && window.FileReader && window.FileList && window.Blob ) ? true : false,
11015					file_input = $('input[name="'+ name +'"][type="file"]', form),
11016					value;
11017				if( file_api && file_input[ 0 ].files[ 0 ] ){
11018					value = file_input[ 0 ].files[ 0 ].name;
11019				} else {
11020					value = file_input.val().replace( "C:\\fakepath\\", '' );
11021				}
11022				if(value.length == 0){
11023					showFieldError(name, 'empty');
11024					return true;
11025				}
11026			}
11027
11028			/* Для input тип text */
11029			if($('input[name="'+ name +'"]', form).length > 0){
11030				var value = $('input[name="'+ name +'"]', form).val();
11031				if(value.length == 0){
11032					showFieldError(name, 'empty');
11033					return true;
11034				}
11035			}
11036
11037			/* Для textarea */
11038			if($('textarea[name="'+ name +'"]', form).length > 0){
11039				var value = $('textarea[name="'+ name +'"]', form).val();
11040				if(value.length == 0){
11041					showFieldError(name, 'empty');
11042					return true;
11043				}
11044			}
11045
11046			/* Для select */
11047			if($('select[name="'+ name +'"]', form).length > 0){
11048				var value = $('select[name="'+ name +'"]', form).val();
11049				if(value.length == 0){
11050					showFieldError(name, 'empty');
11051					return true;
11052				}
11053			}
11054
11055			return false;
11056
11057		};
11058
11059		/* Подсвечивает поля у которых указан тип проверки email */
11060		var checkFieldEmail = function(name){
11061
11062			/* Для input */
11063			if($('input[name="'+ name +'"]', form).length > 0){
11064				var value = $('input[name="'+ name +'"]', form).val();
11065				reg = new RegExp("[0-9a-z_\\-]+@[0-9a-z\\-_^.]+\\.[a-z]{2,10}", 'i');
11066				if(!reg.test(value)){
11067					showFieldError(name, 'email');
11068					return true;
11069				}
11070				else {
11071					return false;
11072				}
11073			}
11074
11075			/* Для textarea */
11076			if($('textarea[name="'+ name +'"]', form).length > 0){
11077				var value = $('textarea[name="'+ name +'"]', form).val();
11078				reg = new RegExp("[0-9a-z_\\-]+@[0-9a-z\\-_^.]+\\.[a-z]{2,10}", 'i');
11079				if(!reg.test(value)){
11080					showFieldError(name, 'email');
11081					return true;
11082				}
11083				else {
11084					return false;
11085				}
11086			}
11087
11088			/* Для select */
11089			if($('select[name="'+ name +'"]', form).length > 0){
11090				var value = $('select[name="'+ name +'"]', form).val();
11091				reg = new RegExp("[0-9a-z_\\-]+@[0-9a-z\\-_^.]+\\.[a-z]{2,10}", 'i');
11092				if(!reg.test(value)){
11093					showFieldError(name, 'email');
11094					return true;
11095				}
11096				else {
11097					return false;
11098				}
11099			}
11100
11101		};
11102
11103		/* Подсвечивает поля у которых указан тип проверки number */
11104		var checkFieldNumber = function(name){
11105
11106			/* Для input */
11107			if($('input[name="'+ name +'"]', form).length > 0){
11108				var value = $('input[name="'+ name +'"]', form).val();
11109				reg = new RegExp("[0-9]", 'i');
11110				if(!reg.test(value)){
11111					showFieldError(name, 'number');
11112					return true;
11113				}
11114				else {
11115					return false;
11116				}
11117			}
11118
11119			/* Для textarea */
11120			if($('textarea[name="'+ name +'"]', form).length > 0){
11121				var value = $('textarea[name="'+ name +'"]', form).val();
11122				reg = new RegExp("[0-9]", 'i');
11123				if(!reg.test(value)){
11124					showFieldError(name, 'number');
11125					return true;
11126				}
11127				else {
11128					return false;
11129				}
11130			}
11131
11132			/* Для select */
11133			if($('select[name="'+ name +'"]', form).length > 0){
11134				var value = $('select[name="'+ name +'"]', form).val();
11135				reg = new RegExp("[0-9]", 'i');
11136				if(!reg.test(value)){
11137					showFieldError(name, 'number');
11138					return true;
11139				}
11140				else {
11141					return false;
11142				}
11143			}
11144
11145		};
11146
11147		/* Выводит ошибки которые приходят с сервера */
11148		var showAllErrors = function(errors){
11149			for(key in errors){
11150				showFieldError(key, errors[key]);
11151			}
11152		};
11153
11154		/* Прячет все ошибки в форме */
11155		var hideAllErrors = function(){
11156			errors = 0;
11157			errorsMessage = {};
11158			/* Убирает класс ошибки у тегов полей */
11159			if(options.errorInput){
11160				$('input', form).removeClass(options.errorClass);
11161				$('textarea', form).removeClass(options.errorClass);
11162				$('select', form).removeClass(options.errorClass);
11163			}
11164			/* Убирает класс ошибки у лейблов */
11165			if(options.errorLabel){
11166				var label = $('label', form).removeClass(options.errorClass);
11167			}
11168			/* Прячет сообщение об ошибках */
11169			if(options.errorMessage){
11170				$(options.message, form).hide();
11171			}
11172		};
11173
11174		/* Прячет ошибки у одного элемента формы */
11175		var hideError = function(elem){
11176			/* Убирает класс error */
11177			if(options.errorInput){
11178				elem.removeClass(options.errorClass);
11179			}
11180			/* Убирает класс error у label для элемента */
11181			if(options.errorLabel){
11182				// Ищем label с id как на элементе
11183				var label = $('label[for="'+ elem.attr('id') +'"]');
11184				// если такой label есть убираем класс ошибки если нет ищем родительский label и удаляем класс с него
11185				if(label.length > 0){
11186					label.removeClass(options.errorClass);
11187				} else if(elem.parent().get(0).tagName == 'LABEL'){
11188					elem.parent().removeClass(options.errorClass);
11189				}
11190			}
11191			/* Прячем сообщение с ошибкой */
11192			if(options.errorMessage){
11193				var message = $(options.message + '[' + options.messageConnector + '="' + elem.attr('name') + '"]', form);
11194				message.fadeOut(100);
11195			}
11196		};
11197
11198		/* Показывает алерт */
11199		var showAlert = function(errors){
11200			var counter = 0;
11201			for(key in errors){
11202				if(options.alerts[key] && counter < 1){
11203					var alert = $(options.alert, form);
11204					var error = errors[key];
11205					alert.empty().append(options.alerts[key][error]).show();
11206					if(options.alertCallback instanceof Function){
11207						options.alertCallback(errors);
11208					}
11209				}
11210				counter++;
11211			}
11212		};
11213
11214		/* Скрывает  */
11215		var hideAlert = function(){
11216			$(options.alert, form).hide();
11217		};
11218
11219		/* Блокирует форму */
11220		var blockForm = function(){
11221			$('input[type="submit"]', form).attr('disabled','disabled');
11222			$('button', form).attr('disabled','disabled');
11223		};
11224
11225		/* Снимает блокировку формы */
11226		var unblockForm = function(){
11227			$('input[type="submit"]', form).removeAttr('disabled');
11228			$('button', form).removeAttr('disabled');
11229		};
11230
11231
11232		var getFormDataObject = function(){
11233			var formData = form.serializeArray();
11234			var dataOut = {};
11235			for(key in formData){
11236				dataOut[formData[key].name] = formData[key].value;
11237			}
11238			return dataOut;
11239		};
11240
11241		/* Конвертирует значения полей */
11242		var convertData = function(formData){
11243			if(!options.convertData instanceof Object){ return;}
11244			for(convertKey in options.convertData){
11245				if(options.convertData[convertKey] instanceof Function){
11246					var result = options.convertData[convertKey](formData[convertKey]);
11247					formData[convertKey] = result;
11248				}
11249			}
11250			return formData;
11251		};
11252
11253		/* Удаляет лишние данные при сабмите формы */
11254		var deleteData = function(formData){
11255			for(key in options.deleteData){
11256				delete formData[options.deleteData[key]];
11257			}
11258			return formData;
11259		};
11260
11261		/* Собственные события */
11262		form.bind('hideErrors', function(){
11263			hideAllErrors();
11264		});
11265
11266
11267
11268		/* Отправка формы */
11269		var formSubmit = function(){
11270
11271            /* Переменные */
11272			var formData,
11273				convertLength = 0;
11274
11275			/* Конвертирует в формат для json */
11276			formData = getFormDataObject();
11277
11278			/* Конвертирует поля по переданным функциям  */
11279			if(options.convertData instanceof Object){
11280				convertLength = $.map(options.convertData, function(n, i) { return i; }).length;
11281				if ( convertLength > 0 ){
11282					formData = convertData(formData);
11283				}
11284			}
11285
11286			/* Добавляет дополнительные данные из mixinData поверх данных формы */
11287			if(options.mixinData instanceof Function){
11288				mixinData = options.mixinData();
11289				formData = $.extend(formData, mixinData || {});
11290			}
11291
11292			/* Удаляет лишние данные */
11293			if(options.deleteData instanceof Object){
11294				formData = deleteData(formData);
11295			}
11296
11297			/* Вызывает callback при сабмите */
11298			if(options.submitCallback instanceof Function){
11299				options.submitCallback(form, formData);
11300			}
11301
11302			$.ajax({
11303				type: options.type,
11304				url: dataUrl,
11305				dataType: options.dataType,
11306				data: formData,
11307				beforeSend: function(){
11308					/* Показывает индикатор загрузки */
11309					loader.fadeIn();
11310					/* Ставит блокировку на форму */
11311					if(options.block == true){
11312						blockForm();
11313					}
11314				},
11315				error: function(data){
11316					loader.fadeOut();
11317					/* Вызывает сallback ошибки валидации формы */
11318					if(options.errorCallback instanceof Function){
11319						options.errorCallback(data);
11320					}
11321				},
11322				success: function(data){
11323					/* Прячет индикатор загрузки */
11324					loader.fadeOut();
11325					/* Снимает блокировку с формы */
11326					if(options.block == true){
11327						unblockForm();
11328					}
11329					if(data.error || (data.status && data.status.toLowerCase() == 'error')){
11330						/* Показывает ошибку */
11331						showAllErrors(data.errors);
11332						/* Показывает алерты */
11333						if(options.alerts && options.errorAlert){
11334							showAlert(data.errors);
11335						}
11336						/* Вызывает сallback ошибки валидации формы */
11337						if(options.errorCallback instanceof Function){
11338							options.errorCallback(data);
11339						}
11340					}
11341					else{
11342						/* Вызывает сallback успешной валидации формы */
11343						if(options.successCallback instanceof Function){
11344							options.successCallback(data, form);
11345						}
11346					}
11347					/* Вызывает force сallback */
11348					if(options.forceCallback instanceof Function){
11349						options.forceCallback(data, form);
11350					}
11351				}
11352			});
11353
11354        };
11355
11356
11357		/* СОБЫТИЯ */
11358
11359		/* Сабмит формы */
11360		form.off('submit').on('submit', function(e){
11361
11362			e.preventDefault(); // отменяет отправку формы
11363
11364			hideAllErrors();    // прячет ошибки
11365			hideAlert();        // прячет алерты
11366
11367			/* Проверяет обязательные для заполнения поля */
11368			errors = checkRules();
11369
11370			/* Вызывает callback и передает в него объект с ошибками */
11371			if(errors > 0 && options.errorCallback instanceof Function){
11372				options.errorCallback(errorsMessage);
11373			}
11374
11375			if (errors == 0){
11376
11377				
11378
11379				/* Проверка на невидимое поле recaptcha */
11380                if ( $( 'input[name="g-recaptcha-response"]', form ).length ) {
11381                    checkCaptchaToken({
11382                        callback: function(token) {
11383                            $('input[name=g-recaptcha-response]', form).val(token);
11384                            formSubmit();
11385                        }
11386                    })
11387                } else {
11388                    formSubmit();
11389                }
11390
11391			}
11392		});
11393
11394		/* Убрать ошибку с input и textarea при изменении */
11395		$('input, textarea', form).on('keydown', function(){
11396			hideError($(this));
11397		});
11398
11399		/* Убрать ошибку с select и input[type="checkbox"] при изменении */
11400		$('input[type="checkbox"], select', form).on('change', function(){
11401			hideError($(this));
11402		});
11403
11404		/* Убрать ошибку с input[type="radio"] при изменении*/
11405		$('input[type="radio"]', form).on('change', function(){
11406			// ищем все radio с name как у измененного и убираем ошибку со всех
11407			$('input[type="radio"][name="'+$(this).attr('name')+'"]', form).each(function(){
11408				hideError($(this));
11409			});
11410		});
11411
11412		return version;
11413
11414	}
11415
11416})(jQuery);
11417;(function ( $, window, document, undefined ) {
11418
11419    var riaVote = function(el, options) {
11420        var defaults = {
11421
11422        };
11423        var _this = this;
11424        _this.el = $(el);
11425        _this.btn = _this.el.find('button');
11426        _this.id = _this.el.data('vote-id').toString();
11427        _this.defOptions = defaults;
11428        _this.userOptions = options;
11429        _this.options = $.extend(true, {}, defaults, options);
11430
11431        _this.init();
11432    };
11433
11434    riaVote.prototype = {
11435        init: function() {
11436            var _this = this;
11437
11438            function checkVoted( id ) {
11439                var lsd = JSON.parse( ria.lsGet( 'ria.ru__ria-votes' ) ) || [];
11440                return lsd.indexOf( id ) > -1;
11441            }
11442
11443            function updateVoted( id, answers ) {
11444                var lsd = JSON.parse( ria.lsGet( 'ria.ru__ria-votes' ) ) || [];
11445                var i = lsd.indexOf( id );
11446                if (i > -1 && i < lsd.length) {
11447                    lsd.splice(i, 1);
11448                }
11449                lsd.push( id );
11450                if ( lsd.length > 100) {
11451                    var removed_id = lsd.shift();
11452                    ria.lsRemove( 'ria-votes_' + removed_id );
11453                }
11454                ria.lsSet( 'ria.ru__ria-votes', JSON.stringify( lsd ) );
11455                ria.lsSet( 'ria-votes_' + id,  JSON.stringify( answers ) );
11456            }
11457
11458            if ( _this.el.hasClass('m-vote-disabled') || checkVoted( _this.id ) ) {
11459                $.ajax({
11460                    url: '/services/vote/get_result/',
11461                    dataType: 'json',
11462                    data: {
11463                        "vote_id": _this.id
11464                    }
11465                }).done(function(response) {
11466                    _this.showResults( response, true );
11467                });
11468                // _this.showResults( {}, true );
11469            }
11470
11471            _this.el.find('form').on('submit', async function(e) {
11472                e.preventDefault();
11473
11474                if ( !checkVoted( _this.id ) ) {
11475                    var formData = $(this).serializeArray();
11476
11477                    let token = await getTokenReCaptcha();
11478                    formData.push({name: "g-recaptcha-response", value: token});
11479
11480                    $.ajax({
11481                        url: $(this).attr('action'),
11482                        dataType: 'json',
11483                        data: formData,
11484                        beforeSend: function() {
11485                            _this.btn.attr('disabled', 'disabled');
11486                        }
11487                    }).done(function(response) {
11488                        _this.showResults( response, true );
11489
11490                        var answers = [];
11491                        $.each(formData, function() {
11492                            if ( this.name == 'vote_answer_id[]' ) {
11493                                answers.push( this.value );
11494                            }
11495                        });
11496                        updateVoted( _this.id, answers );
11497                    });
11498                } else {
11499                    _this.btn.attr('disabled', 'disabled');
11500                    _this.showResults( {}, true );
11501                }
11502            });
11503
11504            _this.el.find('.js-vote-answer').on('click', function() {
11505                if ( _this.el.find('.js-vote-answer input:checked:not(:disabled)').length ) {
11506                    _this.btn.removeAttr('disabled');
11507                } else {
11508                    _this.btn.attr('disabled', 'disabled');
11509                }
11510            });
11511
11512            _this.el.find('.js-vote-switch-button').on('click', function() {
11513                if ( _this.el.hasClass( 'm-vote-results' ) ) {
11514                    _this.el.removeClass( 'm-vote-results' );
11515                } else {
11516                    $.ajax({
11517                        url: '/services/vote/get_result/',
11518                        dataType: 'json',
11519                        data: {
11520                            "vote_id": _this.id
11521                        }
11522                    }).done(function(response) {
11523                        _this.showResults( response );
11524                    });
11525                }
11526            });
11527
11528            // if(typeof grecaptcha !== 'object' && typeof loadReCaptcha === "function") {
11529            //     loadReCaptcha();
11530            // }
11531        },
11532        showResults: function( response, dis ) {
11533            var _this = this;
11534            var lsd = JSON.parse( ria.lsGet( 'ria-votes_' + _this.id ) ) || [];
11535
11536            _this.el.find('.js-vote-answer').each(function() {
11537                if ( typeof response.answers !== 'undefined' && typeof response.answers[ $(this).data('id') ] !== 'undefined' ) {
11538                    var val = response.answers[ $(this).data('id') ].percent;
11539                    var val_text = response.answers[ $(this).data('id') ].percent_text;
11540                    $(this).find('.js-vote-line').width( val+'%' );
11541                    $(this).find('.js-vote-percent span').text( val_text );
11542                } else {
11543                    $(this).find('.js-vote-line').width(0);
11544                    $(this).find('.js-vote-percent span').text(0);
11545                }
11546                if (dis) {
11547                    $(this).find('input').attr('disabled', 'disabled');
11548                    if ( lsd.indexOf( $(this).data('id').toString() ) != -1 ) {
11549                        $(this).find('input').attr('checked', 'checked');
11550                    }
11551                }
11552            });
11553            if ( response.total > 0 || _this.el.find('.js-vote-count-val').text() != '' ) {
11554                _this.el.find('.js-vote-count-val').text( response.total );
11555                _this.el.find('.js-vote-count').removeClass('m-hidden');
11556            } else {
11557                _this.el.find('.js-vote-count').addClass('m-hidden');
11558            }
11559
11560            if (dis) {
11561                _this.el.find('.js-vote-switch-button').addClass('m-hidden');
11562            }
11563            _this.el.addClass( 'm-vote-results' );
11564        }
11565    };
11566
11567    $.fn.riaVote = function(options) {
11568        return this.each(function(){
11569            if(!$.data(this, 'riaVote')){
11570                $.data(this, 'riaVote', new riaVote(this, options));
11571            }
11572        });
11573    };
11574
11575})( jQuery, window, document );
11576
11577/*! jQuery UI - v1.12.1+CommonJS - 2018-02-10
11578 * http://jqueryui.com
11579 * Includes: widget.js
11580 * Copyright jQuery Foundation and other contributors; Licensed MIT */
11581
11582(function( factory ) {
11583  if ( typeof define === "function" && define.amd ) {
11584
11585    // AMD. Register as an anonymous module.
11586    define([ "jquery" ], factory );
11587  } else if ( typeof exports === "object" ) {
11588
11589    // Node/CommonJS
11590    factory( require( "jquery" ) );
11591  } else {
11592
11593    // Browser globals
11594    factory( jQuery );
11595  }
11596}(function( $ ) {
11597
11598  $.ui = $.ui || {};
11599
11600  var version = $.ui.version = "1.12.1";
11601
11602
11603  /*!
11604   * jQuery UI Widget 1.12.1
11605   * http://jqueryui.com
11606   *
11607   * Copyright jQuery Foundation and other contributors
11608   * Released under the MIT license.
11609   * http://jquery.org/license
11610   */
11611
11612  //>>label: Widget
11613  //>>group: Core
11614  //>>description: Provides a factory for creating stateful widgets with a common API.
11615  //>>docs: http://api.jqueryui.com/jQuery.widget/
11616  //>>demos: http://jqueryui.com/widget/
11617
11618
11619
11620  var widgetUuid = 0;
11621  var widgetSlice = Array.prototype.slice;
11622
11623  $.cleanData = ( function( orig ) {
11624    return function( elems ) {
11625      var events, elem, i;
11626      for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
11627        try {
11628
11629          // Only trigger remove when necessary to save time
11630          events = $._data( elem, "events" );
11631          if ( events && events.remove ) {
11632            $( elem ).triggerHandler( "remove" );
11633          }
11634
11635          // Http://bugs.jquery.com/ticket/8235
11636        } catch ( e ) {}
11637      }
11638      orig( elems );
11639    };
11640  } )( $.cleanData );
11641
11642  $.widget = function( name, base, prototype ) {
11643    var existingConstructor, constructor, basePrototype;
11644
11645    // ProxiedPrototype allows the provided prototype to remain unmodified
11646    // so that it can be used as a mixin for multiple widgets (#8876)
11647    var proxiedPrototype = {};
11648
11649    var namespace = name.split( "." )[ 0 ];
11650    name = name.split( "." )[ 1 ];
11651    var fullName = namespace + "-" + name;
11652
11653    if ( !prototype ) {
11654      prototype = base;
11655      base = $.Widget;
11656    }
11657
11658    if ( $.isArray( prototype ) ) {
11659      prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
11660    }
11661
11662    // Create selector for plugin
11663    $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
11664      return !!$.data( elem, fullName );
11665    };
11666
11667    $[ namespace ] = $[ namespace ] || {};
11668    existingConstructor = $[ namespace ][ name ];
11669    constructor = $[ namespace ][ name ] = function( options, element ) {
11670
11671      // Allow instantiation without "new" keyword
11672      if ( !this._createWidget ) {
11673        return new constructor( options, element );
11674      }
11675
11676      // Allow instantiation without initializing for simple inheritance
11677      // must use "new" keyword (the code above always passes args)
11678      if ( arguments.length ) {
11679        this._createWidget( options, element );
11680      }
11681    };
11682
11683    // Extend with the existing constructor to carry over any static properties
11684    $.extend( constructor, existingConstructor, {
11685      version: prototype.version,
11686
11687      // Copy the object used to create the prototype in case we need to
11688      // redefine the widget later
11689      _proto: $.extend( {}, prototype ),
11690
11691      // Track widgets that inherit from this widget in case this widget is
11692      // redefined after a widget inherits from it
11693      _childConstructors: []
11694    } );
11695
11696    basePrototype = new base();
11697
11698    // We need to make the options hash a property directly on the new instance
11699    // otherwise we'll modify the options hash on the prototype that we're
11700    // inheriting from
11701    basePrototype.options = $.widget.extend( {}, basePrototype.options );
11702    $.each( prototype, function( prop, value ) {
11703      if ( !$.isFunction( value ) ) {
11704        proxiedPrototype[ prop ] = value;
11705        return;
11706      }
11707      proxiedPrototype[ prop ] = ( function() {
11708        function _super() {
11709          return base.prototype[ prop ].apply( this, arguments );
11710        }
11711
11712        function _superApply( args ) {
11713          return base.prototype[ prop ].apply( this, args );
11714        }
11715
11716        return function() {
11717          var __super = this._super;
11718          var __superApply = this._superApply;
11719          var returnValue;
11720
11721          this._super = _super;
11722          this._superApply = _superApply;
11723
vendor: 4,189 bytes, lines 11724-11842
11724          returnValue = value.apply( this, arguments );
11725
11726          this._super = __super;
11727          this._superApply = __superApply;
11728
11729          return returnValue;
11730        };
11731      } )();
11732    } );
11733    constructor.prototype = $.widget.extend( basePrototype, {
11734
11735      // TODO: remove support for widgetEventPrefix
11736      // always use the name + a colon as the prefix, e.g., draggable:start
11737      // don't prefix for widgets that aren't DOM-based
11738      widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
11739    }, proxiedPrototype, {
11740      constructor: constructor,
11741      namespace: namespace,
11742      widgetName: name,
11743      widgetFullName: fullName
11744    } );
11745
11746    // If this widget is being redefined then we need to find all widgets that
11747    // are inheriting from it and redefine all of them so that they inherit from
11748    // the new version of this widget. We're essentially trying to replace one
11749    // level in the prototype chain.
11750    if ( existingConstructor ) {
11751      $.each( existingConstructor._childConstructors, function( i, child ) {
11752        var childPrototype = child.prototype;
11753
11754        // Redefine the child widget using the same prototype that was
11755        // originally used, but inherit from the new version of the base
11756        $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
11757          child._proto );
11758      } );
11759
11760      // Remove the list of existing child constructors from the old constructor
11761      // so the old child constructors can be garbage collected
11762      delete existingConstructor._childConstructors;
11763    } else {
11764      base._childConstructors.push( constructor );
11765    }
11766
11767    $.widget.bridge( name, constructor );
11768
11769    return constructor;
11770  };
11771
11772  $.widget.extend = function( target ) {
11773    var input = widgetSlice.call( arguments, 1 );
11774    var inputIndex = 0;
11775    var inputLength = input.length;
11776    var key;
11777    var value;
11778
11779    for ( ; inputIndex < inputLength; inputIndex++ ) {
11780      for ( key in input[ inputIndex ] ) {
11781        value = input[ inputIndex ][ key ];
11782        if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
11783
11784          // Clone objects
11785          if ( $.isPlainObject( value ) ) {
11786            target[ key ] = $.isPlainObject( target[ key ] ) ?
11787              $.widget.extend( {}, target[ key ], value ) :
11788
11789              // Don't extend strings, arrays, etc. with objects
11790              $.widget.extend( {}, value );
11791
11792            // Copy everything else by reference
11793          } else {
11794            target[ key ] = value;
11795          }
11796        }
11797      }
11798    }
11799    return target;
11800  };
11801
11802  $.widget.bridge = function( name, object ) {
11803    var fullName = object.prototype.widgetFullName || name;
11804    $.fn[ name ] = function( options ) {
11805      var isMethodCall = typeof options === "string";
11806      var args = widgetSlice.call( arguments, 1 );
11807      var returnValue = this;
11808
11809      if ( isMethodCall ) {
11810
11811        // If this is an empty collection, we need to have the instance method
11812        // return undefined instead of the jQuery instance
11813        if ( !this.length && options === "instance" ) {
11814          returnValue = undefined;
11815        } else {
11816          this.each( function() {
11817            var methodValue;
11818            var instance = $.data( this, fullName );
11819
11820            if ( options === "instance" ) {
11821              returnValue = instance;
11822              return false;
11823            }
11824
11825            if ( !instance ) {
11826              return $.error( "cannot call methods on " + name +
11827                " prior to initialization; " +
11828                "attempted to call method '" + options + "'" );
11829            }
11830
11831            if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
11832              return $.error( "no such method '" + options + "' for " + name +
11833                " widget instance" );
11834            }
11835
11836            methodValue = instance[ options ].apply( instance, args );
11837
11838            if ( methodValue !== instance && methodValue !== undefined ) {
11839              returnValue = methodValue && methodValue.jquery ?
11840                returnValue.pushStack( methodValue.get() ) :
11841                methodValue;
11842              return false;
vendor: 5,158 bytes, lines 11843-12045
11843            }
11844          } );
11845        }
11846      } else {
11847
11848        // Allow multiple hashes to be passed on init
11849        if ( args.length ) {
11850          options = $.widget.extend.apply( null, [ options ].concat( args ) );
11851        }
11852
11853        this.each( function() {
11854          var instance = $.data( this, fullName );
11855          if ( instance ) {
11856            instance.option( options || {} );
11857            if ( instance._init ) {
11858              instance._init();
11859            }
11860          } else {
11861            $.data( this, fullName, new object( options, this ) );
11862          }
11863        } );
11864      }
11865
11866      return returnValue;
11867    };
11868  };
11869
11870  $.Widget = function( /* options, element */ ) {};
11871  $.Widget._childConstructors = [];
11872
11873  $.Widget.prototype = {
11874    widgetName: "widget",
11875    widgetEventPrefix: "",
11876    defaultElement: "<div>",
11877
11878    options: {
11879      classes: {},
11880      disabled: false,
11881
11882      // Callbacks
11883      create: null
11884    },
11885
11886    _createWidget: function( options, element ) {
11887      element = $( element || this.defaultElement || this )[ 0 ];
11888      this.element = $( element );
11889      this.uuid = widgetUuid++;
11890      this.eventNamespace = "." + this.widgetName + this.uuid;
11891
11892      this.bindings = $();
11893      this.hoverable = $();
11894      this.focusable = $();
11895      this.classesElementLookup = {};
11896
11897      if ( element !== this ) {
11898        $.data( element, this.widgetFullName, this );
11899        this._on( true, this.element, {
11900          remove: function( event ) {
11901            if ( event.target === element ) {
11902              this.destroy();
11903            }
11904          }
11905        } );
11906        this.document = $( element.style ?
11907
11908          // Element within the document
11909          element.ownerDocument :
11910
11911          // Element is window or document
11912          element.document || element );
11913        this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
11914      }
11915
11916      this.options = $.widget.extend( {},
11917        this.options,
11918        this._getCreateOptions(),
11919        options );
11920
11921      this._create();
11922
11923      if ( this.options.disabled ) {
11924        this._setOptionDisabled( this.options.disabled );
11925      }
11926
11927      this._trigger( "create", null, this._getCreateEventData() );
11928      this._init();
11929    },
11930
11931    _getCreateOptions: function() {
11932      return {};
11933    },
11934
11935    _getCreateEventData: $.noop,
11936
11937    _create: $.noop,
11938
11939    _init: $.noop,
11940
11941    destroy: function() {
11942      var that = this;
11943
11944      this._destroy();
11945      $.each( this.classesElementLookup, function( key, value ) {
11946        that._removeClass( value, key );
11947      } );
11948
11949      // We can probably remove the unbind calls in 2.0
11950      // all event bindings should go through this._on()
11951      this.element
11952        .off( this.eventNamespace )
11953        .removeData( this.widgetFullName );
11954      this.widget()
11955        .off( this.eventNamespace )
11956        .removeAttr( "aria-disabled" );
11957
11958      // Clean up events and states
11959      this.bindings.off( this.eventNamespace );
11960    },
11961
11962    _destroy: $.noop,
11963
11964    widget: function() {
11965      return this.element;
11966    },
11967
11968    option: function( key, value ) {
11969      var options = key;
11970      var parts;
11971      var curOption;
11972      var i;
11973
11974      if ( arguments.length === 0 ) {
11975
11976        // Don't return a reference to the internal hash
11977        return $.widget.extend( {}, this.options );
11978      }
11979
11980      if ( typeof key === "string" ) {
11981
11982        // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
11983        options = {};
11984        parts = key.split( "." );
11985        key = parts.shift();
11986        if ( parts.length ) {
11987          curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
11988          for ( i = 0; i < parts.length - 1; i++ ) {
11989            curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
11990            curOption = curOption[ parts[ i ] ];
11991          }
11992          key = parts.pop();
11993          if ( arguments.length === 1 ) {
11994            return curOption[ key ] === undefined ? null : curOption[ key ];
11995          }
11996          curOption[ key ] = value;
11997        } else {
11998          if ( arguments.length === 1 ) {
11999            return this.options[ key ] === undefined ? null : this.options[ key ];
12000          }
12001          options[ key ] = value;
12002        }
12003      }
12004
12005      this._setOptions( options );
12006
12007      return this;
12008    },
12009
12010    _setOptions: function( options ) {
12011      var key;
12012
12013      for ( key in options ) {
12014        this._setOption( key, options[ key ] );
12015      }
12016
12017      return this;
12018    },
12019
12020    _setOption: function( key, value ) {
12021      if ( key === "classes" ) {
12022        this._setOptionClasses( value );
12023      }
12024
12025      this.options[ key ] = value;
12026
12027      if ( key === "disabled" ) {
12028        this._setOptionDisabled( value );
12029      }
12030
12031      return this;
12032    },
12033
12034    _setOptionClasses: function( value ) {
12035      var classKey, elements, currentElements;
12036
12037      for ( classKey in value ) {
12038        currentElements = this.classesElementLookup[ classKey ];
12039        if ( value[ classKey ] === this.options.classes[ classKey ] ||
12040          !currentElements ||
12041          !currentElements.length ) {
12042          continue;
12043        }
12044
12045        // We are doing this to create a new jQuery object because the _removeClass() call
vendor: 8,808 bytes, lines 12046-12309
12046        // on the next line is going to destroy the reference to the current elements being
12047        // tracked. We need to save a copy of this collection so that we can add the new classes
12048        // below.
12049        elements = $( currentElements.get() );
12050        this._removeClass( currentElements, classKey );
12051
12052        // We don't use _addClass() here, because that uses this.options.classes
12053        // for generating the string of classes. We want to use the value passed in from
12054        // _setOption(), this is the new value of the classes option which was passed to
12055        // _setOption(). We pass this value directly to _classes().
12056        elements.addClass( this._classes( {
12057          element: elements,
12058          keys: classKey,
12059          classes: value,
12060          add: true
12061        } ) );
12062      }
12063    },
12064
12065    _setOptionDisabled: function( value ) {
12066      this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
12067
12068      // If the widget is becoming disabled, then nothing is interactive
12069      if ( value ) {
12070        this._removeClass( this.hoverable, null, "ui-state-hover" );
12071        this._removeClass( this.focusable, null, "ui-state-focus" );
12072      }
12073    },
12074
12075    enable: function() {
12076      return this._setOptions( { disabled: false } );
12077    },
12078
12079    disable: function() {
12080      return this._setOptions( { disabled: true } );
12081    },
12082
12083    _classes: function( options ) {
12084      var full = [];
12085      var that = this;
12086
12087      options = $.extend( {
12088        element: this.element,
12089        classes: this.options.classes || {}
12090      }, options );
12091
12092      function processClassString( classes, checkOption ) {
12093        var current, i;
12094        for ( i = 0; i < classes.length; i++ ) {
12095          current = that.classesElementLookup[ classes[ i ] ] || $();
12096          if ( options.add ) {
12097            current = $( $.unique( current.get().concat( options.element.get() ) ) );
12098          } else {
12099            current = $( current.not( options.element ).get() );
12100          }
12101          that.classesElementLookup[ classes[ i ] ] = current;
12102          full.push( classes[ i ] );
12103          if ( checkOption && options.classes[ classes[ i ] ] ) {
12104            full.push( options.classes[ classes[ i ] ] );
12105          }
12106        }
12107      }
12108
12109      this._on( options.element, {
12110        "remove": "_untrackClassesElement"
12111      } );
12112
12113      if ( options.keys ) {
12114        processClassString( options.keys.match( /\S+/g ) || [], true );
12115      }
12116      if ( options.extra ) {
12117        processClassString( options.extra.match( /\S+/g ) || [] );
12118      }
12119
12120      return full.join( " " );
12121    },
12122
12123    _untrackClassesElement: function( event ) {
12124      var that = this;
12125      $.each( that.classesElementLookup, function( key, value ) {
12126        if ( $.inArray( event.target, value ) !== -1 ) {
12127          that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
12128        }
12129      } );
12130    },
12131
12132    _removeClass: function( element, keys, extra ) {
12133      return this._toggleClass( element, keys, extra, false );
12134    },
12135
12136    _addClass: function( element, keys, extra ) {
12137      return this._toggleClass( element, keys, extra, true );
12138    },
12139
12140    _toggleClass: function( element, keys, extra, add ) {
12141      add = ( typeof add === "boolean" ) ? add : extra;
12142      var shift = ( typeof element === "string" || element === null ),
12143        options = {
12144          extra: shift ? keys : extra,
12145          keys: shift ? element : keys,
12146          element: shift ? this.element : element,
12147          add: add
12148        };
12149      options.element.toggleClass( this._classes( options ), add );
12150      return this;
12151    },
12152
12153    _on: function( suppressDisabledCheck, element, handlers ) {
12154      var delegateElement;
12155      var instance = this;
12156
12157      // No suppressDisabledCheck flag, shuffle arguments
12158      if ( typeof suppressDisabledCheck !== "boolean" ) {
12159        handlers = element;
12160        element = suppressDisabledCheck;
12161        suppressDisabledCheck = false;
12162      }
12163
12164      // No element argument, shuffle and use this.element
12165      if ( !handlers ) {
12166        handlers = element;
12167        element = this.element;
12168        delegateElement = this.widget();
12169      } else {
12170        element = delegateElement = $( element );
12171        this.bindings = this.bindings.add( element );
12172      }
12173
12174      $.each( handlers, function( event, handler ) {
12175        function handlerProxy() {
12176
12177          // Allow widgets to customize the disabled handling
12178          // - disabled as an array instead of boolean
12179          // - disabled class as method for disabling individual parts
12180          if ( !suppressDisabledCheck &&
12181            ( instance.options.disabled === true ||
12182              $( this ).hasClass( "ui-state-disabled" ) ) ) {
12183            return;
12184          }
12185          return ( typeof handler === "string" ? instance[ handler ] : handler )
12186            .apply( instance, arguments );
12187        }
12188
12189        // Copy the guid so direct unbinding works
12190        if ( typeof handler !== "string" ) {
12191          handlerProxy.guid = handler.guid =
12192            handler.guid || handlerProxy.guid || $.guid++;
12193        }
12194
12195        var match = event.match( /^([\w:-]*)\s*(.*)$/ );
12196        var eventName = match[ 1 ] + instance.eventNamespace;
12197        var selector = match[ 2 ];
12198
12199        if ( selector ) {
12200          delegateElement.on( eventName, selector, handlerProxy );
12201        } else {
12202          element.on( eventName, handlerProxy );
12203        }
12204      } );
12205    },
12206
12207    _off: function( element, eventName ) {
12208      eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
12209        this.eventNamespace;
12210      element.off( eventName ).off( eventName );
12211
12212      // Clear the stack to avoid memory leaks (#10056)
12213      this.bindings = $( this.bindings.not( element ).get() );
12214      this.focusable = $( this.focusable.not( element ).get() );
12215      this.hoverable = $( this.hoverable.not( element ).get() );
12216    },
12217
12218    _delay: function( handler, delay ) {
12219      function handlerProxy() {
12220        return ( typeof handler === "string" ? instance[ handler ] : handler )
12221          .apply( instance, arguments );
12222      }
12223      var instance = this;
12224      return setTimeout( handlerProxy, delay || 0 );
12225    },
12226
12227    _hoverable: function( element ) {
12228      this.hoverable = this.hoverable.add( element );
12229      this._on( element, {
12230        mouseenter: function( event ) {
12231          this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
12232        },
12233        mouseleave: function( event ) {
12234          this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
12235        }
12236      } );
12237    },
12238
12239    _focusable: function( element ) {
12240      this.focusable = this.focusable.add( element );
12241      this._on( element, {
12242        focusin: function( event ) {
12243          this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
12244        },
12245        focusout: function( event ) {
12246          this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
12247        }
12248      } );
12249    },
12250
12251    _trigger: function( type, event, data ) {
12252      var prop, orig;
12253      var callback = this.options[ type ];
12254
12255      data = data || {};
12256      event = $.Event( event );
12257      event.type = ( type === this.widgetEventPrefix ?
12258        type :
12259        this.widgetEventPrefix + type ).toLowerCase();
12260
12261      // The original event may come from any element
12262      // so we need to reset the target on the new event
12263      event.target = this.element[ 0 ];
12264
12265      // Copy original event properties over to the new event
12266      orig = event.originalEvent;
12267      if ( orig ) {
12268        for ( prop in orig ) {
12269          if ( !( prop in event ) ) {
12270            event[ prop ] = orig[ prop ];
12271          }
12272        }
12273      }
12274
12275      this.element.trigger( event, data );
12276      return !( $.isFunction( callback ) &&
12277        callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
12278        event.isDefaultPrevented() );
12279    }
12280  };
12281
12282  $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
12283    $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
12284      if ( typeof options === "string" ) {
12285        options = { effect: options };
12286      }
12287
12288      var hasOptions;
12289      var effectName = !options ?
12290        method :
12291        options === true || typeof options === "number" ?
12292        defaultEffect :
12293        options.effect || defaultEffect;
12294
12295      options = options || {};
12296      if ( typeof options === "number" ) {
12297        options = { duration: options };
12298      }
12299
12300      hasOptions = !$.isEmptyObject( options );
12301      options.complete = callback;
12302
12303      if ( options.delay ) {
12304        element.delay( options.delay );
12305      }
12306
12307      if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
12308        element[ method ]( options );
12309      } else if ( effectName !== method && element[ effectName ] ) {
12310        element[ effectName ]( options.duration, options.easing, callback );
12311      } else {
12312        element.queue( function( next ) {
12313          $( this )[ method ]();
12314          if ( callback ) {
12315            callback.call( element[ 0 ] );
12316          }
12317          next();
12318        } );
12319      }
12320    };
12321  } );
12322
12323  var widget = $.widget;
12324
12325
12326
12327
12328}));
12329
12330/*
12331 * jQuery File Upload Plugin
12332 * https://github.com/blueimp/jQuery-File-Upload
12333 *
12334 * Copyright 2010, Sebastian Tschan
12335 * https://blueimp.net
12336 *
12337 * Licensed under the MIT license:
12338 * https://opensource.org/licenses/MIT
12339 */
12340
12341/* jshint nomen:false */
12342/* global define, require, window, document, location, Blob, FormData */
12343
12344;(function (factory) {
12345    'use strict';
12346    if (typeof define === 'function' && define.amd) {
12347        // Register as an anonymous AMD module:
12348        define([
12349            'jquery',
12350            'jquery-ui/ui/widget'
12351        ], factory);
12352    } else if (typeof exports === 'object') {
12353        // Node/CommonJS:
12354        factory(
12355            require('jquery'),
12356            require('./vendor/jquery.ui.widget')
12357        );
12358    } else {
12359        // Browser globals:
12360        factory(window.jQuery);
12361    }
12362}(function ($) {
12363    'use strict';
12364
12365    // Detect file input support, based on
12366    // http://viljamis.com/blog/2012/file-upload-support-on-mobile/
12367    $.support.fileInput = !(new RegExp(
12368        // Handle devices which give false positives for the feature detection:
12369        '(Android (1\\.[0156]|2\\.[01]))' +
12370            '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +
12371            '|(w(eb)?OSBrowser)|(webOS)' +
12372            '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
12373    ).test(window.navigator.userAgent) ||
12374        // Feature detection for all other devices:
12375        $('<input type="file"/>').prop('disabled'));
12376
12377    // The FileReader API is not actually used, but works as feature detection,
12378    // as some Safari versions (5?) support XHR file uploads via the FormData API,
12379    // but not non-multipart XHR file uploads.
12380    // window.XMLHttpRequestUpload is not available on IE10, so we check for
12381    // window.ProgressEvent instead to detect XHR2 file upload capability:
12382    $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);
12383    $.support.xhrFormDataFileUpload = !!window.FormData;
12384
12385    // Detect support for Blob slicing (required for chunked uploads):
12386    $.support.blobSlice = window.Blob && (Blob.prototype.slice ||
12387        Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
12388
12389    // Helper function to create drag handlers for dragover/dragenter/dragleave:
12390    function getDragHandler(type) {
12391        var isDragOver = type === 'dragover';
12392        return function (e) {
12393            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
12394            var dataTransfer = e.dataTransfer;
12395            if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&
12396                    this._trigger(
12397                        type,
12398                        $.Event(type, {delegatedEvent: e})
12399                    ) !== false) {
12400                e.preventDefault();
12401                if (isDragOver) {
12402                    dataTransfer.dropEffect = 'copy';
12403                }
12404            }
12405        };
12406    }
12407
12408    // The fileupload widget listens for change events on file input fields defined
12409    // via fileInput setting and paste or drop events of the given dropZone.
12410    // In addition to the default jQuery Widget methods, the fileupload widget
12411    // exposes the "add" and "send" methods, to add or directly send files using
12412    // the fileupload API.
12413    // By default, files added via file input selection, paste, drag & drop or
12414    // "add" method are uploaded immediately, but it is possible to override
12415    // the "add" callback option to queue file uploads.
12416    $.widget('blueimp.fileupload', {
12417
12418        options: {
12419            // The drop target element(s), by the default the complete document.
12420            // Set to null to disable drag & drop support:
12421            dropZone: $(document),
12422            // The paste target element(s), by the default undefined.
12423            // Set to a DOM node or jQuery object to enable file pasting:
12424            pasteZone: undefined,
12425            // The file input field(s), that are listened to for change events.
12426            // If undefined, it is set to the file input fields inside
12427            // of the widget element on plugin initialization.
12428            // Set to null to disable the change listener.
12429            fileInput: undefined,
12430            // By default, the file input field is replaced with a clone after
12431            // each input field change event. This is required for iframe transport
12432            // queues and allows change events to be fired for the same file
12433            // selection, but can be disabled by setting the following option to fal
12433se:
12434            replaceFileInput: true,
12435            // The parameter name for the file form data (the request argument name).
12436            // If undefined or empty, the name property of the file input field is
12437            // used, or "files[]" if the file input name property is also empty,
12438            // can be a string or an array of strings:
12439            paramName: undefined,
12440            // By default, each file of a selection is uploaded using an individual
12441            // request for XHR type uploads. Set to false to upload file
12442            // selections in one request each:
12443            singleFileUploads: true,
12444            // To limit the number of files uploaded with one XHR request,
12445            // set the following option to an integer greater than 0:
12446            limitMultiFileUploads: undefined,
12447            // The following option limits the number of files uploaded with one
12448            // XHR request to keep the request size under or equal to the defined
12449            // limit in bytes:
12450            limitMultiFileUploadSize: undefined,
12451            // Multipart file uploads add a number of bytes to each uploaded file,
12452            // therefore the following option adds an overhead for each file used
12453            // in the limitMultiFileUploadSize configuration:
12454            limitMultiFileUploadSizeOverhead: 512,
12455            // Set the following option to true to issue all file upload requests
12456            // in a sequential order:
12457            sequentialUploads: false,
12458            // To limit the number of concurrent uploads,
12459            // set the following option to an integer greater than 0:
12460            limitConcurrentUploads: undefined,
12461            // Set the following option to true to force iframe transport uploads:
12462            forceIframeTransport: false,
12463            // Set the following option to the location of a redirect url on the
12464            // origin server, for cross-domain iframe transport uploads:
12465            redirect: undefined,
12466            // The parameter name for the redirect url, sent as part of the form
12467            // data and set to 'redirect' if this option is empty:
12468            redirectParamName: undefined,
12469            // Set the following option to the location of a postMessage window,
12470            // to enable postMessage transport uploads:
12471            postMessage: undefined,
12472            // By default, XHR file uploads are sent as multipart/form-data.
12473            // The iframe transport is always using multipart/form-data.
12474            // Set to false to enable non-multipart XHR uploads:
12475            multipart: true,
12476            // To upload large files in smaller chunks, set the following option
12477            // to a preferred maximum chunk size. If set to 0, null or undefined,
12478            // or the browser does not support the required Blob API, files will
12479            // be uploaded as a whole.
12480            maxChunkSize: undefined,
12481            // When a non-multipart upload or a chunked multipart upload has been
12482            // aborted, this option can be used to resume the upload by setting
12483            // it to the size of the already uploaded bytes. This option is most
12484            // useful when modifying the options object inside of the "add" or
12485            // "send" callbacks, as the options are cloned for each file upload.
12486            uploadedBytes: undefined,
12487            // By default, failed (abort or error) file uploads are removed from the
12488            // global progress calculation. Set the following option to false to
12489            // prevent recalculating the global progress data:
12490            recalculateProgress: true,
12491            // Interval in milliseconds to calculate and trigger progress events:
12492            progressInterval: 100,
12493            // Interval in milliseconds to calculate progress bitrate:
12494            bitrateInterval: 500,
12495            // By default, uploads are started automatically when adding files:
12496            autoUpload: true,
12497
12498            // Error and info messages:
12499            messages: {
12500                uploadedBytes: 'Uploaded bytes exceed file size'
12501            },
12502
12503            // Translation function, gets the message key to be translated
12504            // and an object with context specific data as arguments:
12505            i18n: function (message, context) {
12506                message = this.messages[message] || message.toString();
12507                if (context) {
12508                    $.each(context, function (key, value) {
12509                        message = message.replace('{' + key + '}', value);
12510                    });
12511                }
12512                return message;
12513            },
12514
12515            // Additional form data to be sent along with the file uploads can be set
12516            // using this option, which accepts an array of objects with name and
12517            // value properties, a function returning such an array, a FormData
12518            // object (for XHR file uploads), or a simple object.
12519            // The form of the first fileInput is given as parameter to the function:
12520            formData: function (form) {
12521                return form.serializeArray();
12522            },
12523
12524            // The add callback is invoked as soon as files are added to the fileupload
12525            // widget (via file input selection, drag & drop, paste or add API call).
12526            // If the singleFileUploads option is enabled, this callback will be
12527            // called once for each file in the selection for XHR file uploads, else
12528            // once for each file selection.
12529            //
12530            // The upload starts when the submit method is invoked on the data parameter.
12531            // The data object contains a files property holding the added files
12532            // and allows you to override plugin options as well as define ajax settings.
12533            //
12534            // Listeners for this callback can also be bound the following way:
12535            // .bind('fileuploadadd', func);
12536            //
12537            // data.submit() returns a Promise object and allows to attach additional
12538            // handlers using jQuery's Deferred callbacks:
12539            // data.submit().done(func).fail(func).always(func);
12540            add: function (e, data) {
12541                if (e.isDefaultPrevented()) {
12542                    return false;
12543                }
12544                if (data.autoUpload || (data.autoUpload !== false &&
12545                        $(this).fileupload('option', 'autoUpload'))) {
12546                    data.process().done(function () {
12547                        data.submit();
12548                    });
12549                }
12550            },
12551
12552            // Other callbacks:
12553
12554            // Callback for the submit event of each file upload:
12555            // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
12556
12557            // Callback for the start of each file upload request:
12558            // send: function (e, data) {}, // .bind('fileuploadsend', func);
12559
12560            // Callback for successful uploads:
12561            // done: function (e, data) {}, // .bind('fileuploaddone', func);
12562
12563            // Callback for failed (abort or error) uploads:
12564            // fail: function (e, data) {}, // .bind('fileuploadfail', func);
12565
12566            // Callback for completed (success, abort or error) requests:
12567            // always: function (e, data) {}, // .bind('fileuploadalways', func);
12568
12569            // Callback for upload progress events:
12570            // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
12571
12572            // Callback for global upload progress events:
12573            // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
12574
12575            // Callback for uploads start, equivalent to the global ajaxStart event:
12576            // start: function (e) {}, // .bind('fileuploadstart', func);
12577
12578            // Callback for uploads stop, equivalent to the global ajaxStop event:
12579            // stop: function (e) {}, // .bind('fileuploadstop', func);
12580
12581            // Callback for change events of the fileInput(s):
12582            // change: function (e, data) {}, // .bind('fileuploadchange', func);
12583
12584            // Callback for paste events to the pasteZone(s):
12585            // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
12586
12587            // Callback for drop events of the dropZone(s):
12588            // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
12589
12590            // Callback for dragover events of the dropZone(s):
12591            // dragover: function (e) {}, // .bind('fileuploaddragover', func);
12592
12593            // Callback for the start of each chunk upload request:
12594            // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);
12595
12596            // Callback for successful chunk uploads:
12597            // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);
12598
12599            // Callback for failed (abort or error) chunk uploads:
12600            // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);
12601
12602            // Callback for completed (success, abort or error) chunk upload requests:
12603            // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);
12604
12605            // The plugin options are used as settings object for the ajax calls.
12606            // The following are jQuery ajax settings required for the file uploads:
12607            processData: false,
12608            contentType: false,
12609            cache: false,
12610            timeout: 0
12611        },
12612
12613        // A list of options that require reinitializing event listeners and/or
12614        // special initialization code:
12615        _specialOptions: [
12616            'fileInput',
12617            'dropZone',
12618            'pasteZone',
12619            'multipart',
12620            'forceIframeTransport'
12621        ],
12622
12623        _blobSlice: $.support.blobSlice && function () {
12624            var slice = this.slice || this.webkitSlice || this.mozSlice;
12625            return slice.apply(this, arguments);
12626        },
12627
12628        _BitrateTimer: function () {
12629            this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
12630            this.loaded = 0;
12631            this.bitrate = 0;
12632            this.getBitrate = function (now, loaded, interval) {
12633                var timeDiff = now - this.timestamp;
12634                if (!this.bitrate || !interval || timeDiff > interval) {
12635                    this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
12636                    this.loaded = loaded;
12637                    this.timestamp = now;
12638                }
12639                return this.bitrate;
12640            };
12641        },
12642
12643        _isXHRUpload: function (options) {
12644            return !options.forceIframeTransport &&
12645                ((!options.multipart && $.support.xhrFileUpload) ||
12646                $.support.xhrFormDataFileUpload);
12647        },
12648
12649        _getFormData: function (options) {
12650            var formData;
12651            if ($.type(options.formData) === 'function') {
12652                return options.formData(options.form);
12653            }
12654            if ($.isArray(options.formData)) {
12655                return options.formData;
12656            }
12657            if ($.type(options.formData) === 'object') {
12658                formData = [];
12659                $.each(options.formData, function (name, value) {
12660                    formData.push({name: name, value: value});
12661                });
12662                return formData;
12663            }
12664            return [];
12665        },
12666
12667        _getTotal: function (files) {
12668            var total = 0;
12669            $.each(files, function (index, file) {
12670                total += file.size || 1;
12671            });
12672            return total;
12673        },
12674
12675        _initProgressObject: function (obj) {
12676            var progress = {
12677                loaded: 0,
12678                total: 0,
12679                bitrate: 0
12680            };
12681            if (obj._progress) {
12682                $.extend(obj._progress, progress);
12683            } else {
12684                obj._progress = progress;
12685            }
12686        },
12687
12688        _initResponseObject: function (obj) {
12689            var prop;
12690            if (obj._response) {
12691                for (prop in obj._response) {
12692                    if (obj._response.hasOwnProperty(prop)) {
12693                        delete obj._response[prop];
12694                    }
12695                }
12696            } else {
12697                obj._response = {};
12698            }
12699        },
12700
12701        _onProgress: function (e, data) {
12702            if (e.lengthComputable) {
12703                var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
12704                    loaded;
12705                if (data._time && data.progressInterval &&
12706                        (now - data._time < data.progressInterval) &&
12707                        e.loaded !== e.total) {
12708                    return;
12709                }
12710                data._time = now;
12711                loaded = Math.floor(
12712                    e.loaded / e.total * (data.chunkSize || data._progress.total)
12713                ) + (data.uploadedBytes || 0);
12714                // Add the difference from the previously loaded state
12715                // to the global loaded counter:
12716                this._progress.loaded += (loaded - data._progress.loaded);
12717                this._progress.bitrate = this._bitrateTimer.getBitrate(
12718                    now,
12719                    this._progress.loaded,
12720                    data.bitrateInterval
12721                );
12722                data._progress.loaded = data.loaded = loaded;
12723                data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
12724                    now,
12725                    loaded,
12726                    data.bitrateInterval
12727                );
12728                // Trigger a custom progress event with a total data property set
12729                // to the file size(s) of the current upload and a loaded data
12730                // property calculated accordingly:
12731                this._trigger(
12732                    'progress',
12733                    $.Event('progress', {delegatedEvent: e}),
12734                    data
12735                );
12736                // Trigger a global progress event for all current file uploads,
12737                // including ajax calls queued for sequential file uploads:
12738                this._trigger(
12739                    'progressall',
12740                    $.Event('progressall', {delegatedEvent: e}),
12741                    this._progress
12742                );
12743            }
12744        },
12745
12746        _initProgressListener: function (options) {
12747            var that = this,
12748                xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
12749            // Accesss to the native XHR object is required to add event listeners
12750            // for the upload progress event:
12751            if (xhr.upload) {
12752                $(xhr.upload).bind('progress', function (e) {
12753                    var oe = e.originalEvent;
12754                    // Make sure the progress event properties get copied over:
12755                    e.lengthComputable = oe.lengthComputable;
12756                    e.loaded = oe.loaded;
12757                    e.total = oe.total;
12758                    that._onProgress(e, options);
12759                });
12760                options.xhr = function () {
12761                    return xhr;
12762                };
12763            }
12764        },
12765
12766        _isInstanceOf: function (type, obj) {
12767            // Cross-frame instanceof check
12768            return Object.prototype.toString.call(obj) === '[object ' + type + ']';
12769        },
12770
12771        _initXHRData: function (options) {
12772            var that = this,
12773                formData,
12774                file = options.files[0],
12775                // Ignore non-multipart setting if not supported:
12776                multipart = options.multipart || !$.support.xhrFileUpload,
12777                paramName = $.type(options.paramName) === 'array' ?
12778                    options.paramName[0] : options.paramName;
12779            options.headers = $.extend({}, options.headers);
12780            if (options.contentRange) {
12781                options.headers['Content-Range'] = options.contentRange;
12782            }
12783            if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
12784                options.headers['Content-Disposition'] = 'attachment; filename="' +
12785                    encodeURI(file.uploadName || file.name) + '"';
12786            }
12787            if (!multipart) {
12788                options.contentType = file.type || 'application/octet-stream';
12789                options.data = options.blob || file;
12790            } else if ($.support.xhrFormDataFileUpload) {
12791                if (options.postMessage) {
12792                    // window.postMessage does not allow sending FormData
12793                    // objects, so we just add the File/Blob objects to
12794                    // the formData array and let the postMessage window
12795                    // create the FormData object out of this array:
12796                    formData = this._getFormData(options);
12797                    if (options.blob) {
12798                        formData.push({
12799                            name: paramName,
12800                            value: options.blob
12801                        });
12802                    } else {
12803                        $.each(options.files, function (index, file) {
12804                            formData.push({
12805                                name: ($.type(options.paramName) === 'array' &&
12806                                    options.paramName[index]) || paramName,
12807                                value: file
12808                            });
12809                        });
12810                    }
12811                } else {
12812                    if (that._isInstanceOf('FormData', options.formData)) {
12813                        formData = options.formData;
12814                    } else {
12815                        formData = new FormData();
12816                        $.each(this._getFormData(options), function (index, field) {
12817                            formData.append(field.name, field.value);
12818                        });
12819                    }
12820                    if (options.blob) {
12821                        formData.append(
12822                            paramName,
12823                            options.blob,
12824                            file.uploadName || file.name
12825                        );
12826                    } else {
12827                        $.each(options.files, function (index, file) {
12828                            // This check allows the tests to run with
12829                            // dummy objects:
12830                            if (that._isInstanceOf('File', file) ||
12831                                    that._isInstanceOf('Blob', file)) {
12832                                formData.append(
12833                                    ($.type(options.paramName) === 'array' &&
12834                                        options.paramName[index]) || paramName,
12835                                    file,
12836                                    file.uploadName || file.name
12837                                );
12838                            }
12839                        });
12840                    }
12841                }
12842                options.data = formData;
12843            }
12844            // Blob reference is not needed anymore, free memory:
12845            options.blob = null;
12846        },
12847
12848        _initIframeSettings: function (options) {
12849            var targetHost = $('<a></a>').prop('href', options.url).prop('host');
12850            // Setting the dataType to iframe enables the iframe transport:
12851            options.dataType = 'iframe ' + (options.dataType || '');
12852            // The iframe transport accepts a serialized array as form data:
12853            options.formData = this._getFormData(options);
12854            // Add redirect url to form data on cross-domain uploads:
12855            if (options.redirect && targetHost && targetHost !== location.host) {
12856                options.formData.push({
12857                    name: options.redirectParamName || 'redirect',
12858                    value: options.redirect
12859                });
12860            }
12861        },
12862
12863        _initDataSettings: function (options) {
12864            if (this._isXHRUpload(options)) {
12865                if (!this._chunkedUpload(options, true)) {
12866                    if (!options.data) {
12867                        this._initXHRData(options);
12868                    }
12869                    this._initProgressListener(options);
12870                }
12871                if (options.postMessage) {
12872                    // Setting the dataType to postmessage enables the
12873                    // postMessage transport:
12874                    options.dataType = 'postmessage ' + (options.dataType || '');
12875                }
12876            } else {
12877                this._initIframeSettings(options);
12878            }
12879        },
12880
12881        _getParamName: function (options) {
12882            var fileInput = $(options.fileInput),
12883                paramName = options.paramName;
12884            if (!paramName) {
12885                paramName = [];
12886                fileInput.each(function () {
12887                    var input = $(this),
12888                        name = input.prop('name') || 'files[]',
12889                        i = (input.prop('files') || [1]).length;
12890                    while (i) {
12891                        paramName.push(name);
12892                        i -= 1;
12893                    }
12894                });
12895                if (!paramName.length) {
12896                    paramName = [fileInput.prop('name') || 'files[]'];
12897                }
12898            } else if (!$.isArray(paramName)) {
12899                paramName = [paramName];
12900            }
12901            return paramName;
12902        },
12903
12904        _initFormSettings: function (options) {
12905            // Retrieve missing options from the input field and the
12906            // associated form, if available:
12907            if (!options.form || !options.form.length) {
12908                options.form = $(options.fileInput.prop('form'));
12909                // If the given file input doesn't have an associated form,
12910                // use the default widget file input's form:
12911                if (!options.form.length) {
12912                    options.form = $(this.options.fileInput.prop('form'));
12913                }
12914            }
12915            options.paramName = this._getParamName(options);
12916            if (!options.url) {
12917                options.url = options.form.prop('action') || location.href;
12918            }
12919            // The HTTP request method must be "POST" or "PUT":
12920            options.type = (options.type ||
12921                ($.type(options.form.prop('method')) === 'string' &&
12922                    options.form.prop('method')) || ''
12923                ).toUpperCase();
12924            if (options.type !== 'POST' && options.type !== 'PUT' &&
12925                    options.type !== 'PATCH') {
12926                options.type = 'POST';
12927            }
12928            if (!options.formAcceptCharset) {
12929                options.formAcceptCharset = options.form.attr('accept-charset');
12930            }
12931        },
12932
12933        _getAJAXSettings: function (data) {
12934            var options = $.extend({}, this.options, data);
12935            this._initFormSettings(options);
12936            this._initDataSettings(options);
12937            return options;
12938        },
12939
12940        // jQuery 1.6 doesn't provide .state(),
12941        // while jQuery 1.8+ removed .isRejected() and .isResolved():
12942        _getDeferredState: function (deferred) {
12943            if (deferred.state) {
12944                return deferred.state();
12945            }
12946            if (deferred.isResolved()) {
12947                return 'resolved';
12948            }
12949            if (deferred.isRejected()) {
12950                return 'rejected';
12951            }
12952            return 'pending';
12953        },
12954
12955        // Maps jqXHR callbacks to the equivalent
12956        // methods of the given Promise object:
12957        _enhancePromise: function (promise) {
12958            promise.success = promise.done;
12959            promise.error = promise.fail;
12960            promise.complete = promise.always;
12961            return promise;
12962        },
12963
12964        // Creates and returns a Promise object enhanced with
12965        // the jqXHR methods abort, success, error and complete:
12966        _getXHRPromise: function (resolveOrReject, context, args
12966) {
12967            var dfd = $.Deferred(),
12968                promise = dfd.promise();
12969            context = context || this.options.context || promise;
12970            if (resolveOrReject === true) {
12971                dfd.resolveWith(context, args);
12972            } else if (resolveOrReject === false) {
12973                dfd.rejectWith(context, args);
12974            }
12975            promise.abort = dfd.promise;
12976            return this._enhancePromise(promise);
12977        },
12978
12979        // Adds convenience methods to the data callback argument:
12980        _addConvenienceMethods: function (e, data) {
12981            var that = this,
12982                getPromise = function (args) {
12983                    return $.Deferred().resolveWith(that, args).promise();
12984                };
12985            data.process = function (resolveFunc, rejectFunc) {
12986                if (resolveFunc || rejectFunc) {
12987                    data._processQueue = this._processQueue =
12988                        (this._processQueue || getPromise([this])).then(
12989                            function () {
12990                                if (data.errorThrown) {
12991                                    return $.Deferred()
12992                                        .rejectWith(that, [data]).promise();
12993                                }
12994                                return getPromise(arguments);
12995                            }
12996                        ).then(resolveFunc, rejectFunc);
12997                }
12998                return this._processQueue || getPromise([this]);
12999            };
13000            data.submit = function () {
13001                if (this.state() !== 'pending') {
13002                    data.jqXHR = this.jqXHR =
13003                        (that._trigger(
13004                            'submit',
13005                            $.Event('submit', {delegatedEvent: e}),
13006                            this
13007                        ) !== false) && that._onSend(e, this);
13008                }
13009                return this.jqXHR || that._getXHRPromise();
13010            };
13011            data.abort = function () {
13012                if (this.jqXHR) {
13013                    return this.jqXHR.abort();
13014                }
13015                this.errorThrown = 'abort';
13016                that._trigger('fail', null, this);
13017                return that._getXHRPromise(false);
13018            };
13019            data.state = function () {
13020                if (this.jqXHR) {
13021                    return that._getDeferredState(this.jqXHR);
13022                }
13023                if (this._processQueue) {
13024                    return that._getDeferredState(this._processQueue);
13025                }
13026            };
13027            data.processing = function () {
13028                return !this.jqXHR && this._processQueue && that
13029                    ._getDeferredState(this._processQueue) === 'pending';
13030            };
13031            data.progress = function () {
13032                return this._progress;
13033            };
13034            data.response = function () {
13035                return this._response;
13036            };
13037        },
13038
13039        // Parses the Range header from the server response
13040        // and returns the uploaded bytes:
13041        _getUploadedBytes: function (jqXHR) {
13042            var range = jqXHR.getResponseHeader('Range'),
13043                parts = range && range.split('-'),
13044                upperBytesPos = parts && parts.length > 1 &&
13045                    parseInt(parts[1], 10);
13046            return upperBytesPos && upperBytesPos + 1;
13047        },
13048
13049        // Uploads a file in multiple, sequential requests
13050        // by splitting the file up in multiple blob chunks.
13051        // If the second parameter is true, only tests if the file
13052        // should be uploaded in chunks, but does not invoke any
13053        // upload requests:
13054        _chunkedUpload: function (options, testOnly) {
13055            options.uploadedBytes = options.uploadedBytes || 0;
13056            var that = this,
13057                file = options.files[0],
13058                fs = file.size,
13059                ub = options.uploadedBytes,
13060                mcs = options.maxChunkSize || fs,
13061                slice = this._blobSlice,
13062                dfd = $.Deferred(),
13063                promise = dfd.promise(),
13064                jqXHR,
13065                upload;
13066            if (!(this._isXHRUpload(options) && slice && (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)) ||
13067                    options.data) {
13068                return false;
13069            }
13070            if (testOnly) {
13071                return true;
13072            }
13073            if (ub >= fs) {
13074                file.error = options.i18n('uploadedBytes');
13075                return this._getXHRPromise(
13076                    false,
13077                    options.context,
13078                    [null, 'error', file.error]
13079                );
13080            }
13081            // The chunk upload method:
13082            upload = function () {
13083                // Clone the options object for each chunk upload:
13084                var o = $.extend({}, options),
13085                    currentLoaded = o._progress.loaded;
13086                o.blob = slice.call(
13087                    file,
13088                    ub,
13089                    ub + ($.type(mcs) === 'function' ? mcs(o) : mcs),
13090                    file.type
13091                );
13092                // Store the current chunk size, as the blob itself
13093                // will be dereferenced after data processing:
13094                o.chunkSize = o.blob.size;
13095                // Expose the chunk bytes position range:
13096                o.contentRange = 'bytes ' + ub + '-' +
13097                    (ub + o.chunkSize - 1) + '/' + fs;
13098                // Process the upload data (the blob and potential form data):
13099                that._initXHRData(o);
13100                // Add progress listeners for this chunk upload:
13101                that._initProgressListener(o);
13102                jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
13103                        that._getXHRPromise(false, o.context))
13104                    .done(function (result, textStatus, jqXHR) {
13105                        ub = that._getUploadedBytes(jqXHR) ||
13106                            (ub + o.chunkSize);
13107                        // Create a progress event if no final progress event
13108                        // with loaded equaling total has been triggered
13109                        // for this chunk:
13110                        if (currentLoaded + o.chunkSize - o._progress.loaded) {
13111                            that._onProgress($.Event('progress', {
13112                                lengthComputable: true,
13113                                loaded: ub - o.uploadedBytes,
13114                                total: ub - o.uploadedBytes
13115                            }), o);
13116                        }
13117                        options.uploadedBytes = o.uploadedBytes = ub;
13118                        o.result = result;
13119                        o.textStatus = textStatus;
13120                        o.jqXHR = jqXHR;
13121                        that._trigger('chunkdone', null, o);
13122                        that._trigger('chunkalways', null, o);
13123                        if (ub < fs) {
13124                            // File upload not yet complete,
13125                            // continue with the next chunk:
13126                            upload();
13127                        } else {
13128                            dfd.resolveWith(
13129                                o.context,
13130                                [result, textStatus, jqXHR]
13131                            );
13132                        }
13133                    })
13134                    .fail(function (jqXHR, textStatus, errorThrown) {
13135                        o.jqXHR = jqXHR;
13136                        o.textStatus = textStatus;
13137                        o.errorThrown = errorThrown;
13138                        that._trigger('chunkfail', null, o);
13139                        that._trigger('chunkalways', null, o);
13140                        dfd.rejectWith(
13141                            o.context,
13142                            [jqXHR, textStatus, errorThrown]
13143                        );
13144                    });
13145            };
13146            this._enhancePromise(promise);
13147            promise.abort = function () {
13148                return jqXHR.abort();
13149            };
13150            upload();
13151            return promise;
13152        },
13153
13154        _beforeSend: function (e, data) {
13155            if (this._active === 0) {
13156                // the start callback is triggered when an upload starts
13157                // and no other uploads are currently running,
13158                // equivalent to the global ajaxStart event:
13159                this._trigger('start');
13160                // Set timer for global bitrate progress calculation:
13161                this._bitrateTimer = new this._BitrateTimer();
13162                // Reset the global progress values:
13163                this._progress.loaded = this._progress.total = 0;
13164                this._progress.bitrate = 0;
13165            }
13166            // Make sure the container objects for the .response() and
13167            // .progress() methods on the data object are available
13168            // and reset to their initial state:
13169            this._initResponseObject(data);
13170            this._initProgressObject(data);
13171            data._progress.loaded = data.loaded = data.uploadedBytes || 0;
13172            data._progress.total = data.total = this._getTotal(data.files) || 1;
13173            data._progress.bitrate = data.bitrate = 0;
13174            this._active += 1;
13175            // Initialize the global progress values:
13176            this._progress.loaded += data.loaded;
13177            this._progress.total += data.total;
13178        },
13179
13180        _onDone: function (result, textStatus, jqXHR, options) {
13181            var total = options._progress.total,
13182                response = options._response;
13183            if (options._progress.loaded < total) {
13184                // Create a progress event if no final progress event
13185                // with loaded equaling total has been triggered:
13186                this._onProgress($.Event('progress', {
13187                    lengthComputable: true,
13188                    loaded: total,
13189                    total: total
13190                }), options);
13191            }
13192            response.result = options.result = result;
13193            response.textStatus = options.textStatus = textStatus;
13194            response.jqXHR = options.jqXHR = jqXHR;
13195            this._trigger('done', null, options);
13196        },
13197
13198        _onFail: function (jqXHR, textStatus, errorThrown, options) {
13199            var response = options._response;
13200            if (options.recalculateProgress) {
13201                // Remove the failed (error or abort) file upload from
13202                // the global progress calculation:
13203                this._progress.loaded -= options._progress.loaded;
13204                this._progress.total -= options._progress.total;
13205            }
13206            response.jqXHR = options.jqXHR = jqXHR;
13207            response.textStatus = options.textStatus = textStatus;
13208            response.errorThrown = options.errorThrown = errorThrown;
13209            this._trigger('fail', null, options);
13210        },
13211
13212        _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
13213            // jqXHRorResult, textStatus and jqXHRorError are added to the
13214            // options object via done and fail callbacks
13215            this._trigger('always', null, options);
13216        },
13217
13218        _onSend: function (e, data) {
13219            if (!data.submit) {
13220                this._addConvenienceMethods(e, data);
13221            }
13222            var that = this,
13223                jqXHR,
13224                aborted,
13225                slot,
13226                pipe,
13227                options = that._getAJAXSettings(data),
13228                send = function () {
13229                    that._sending += 1;
13230                    // Set timer for bitrate progress calculation:
13231                    options._bitrateTimer = new that._BitrateTimer();
13232                    jqXHR = jqXHR || (
13233                        ((aborted || that._trigger(
13234                            'send',
13235                            $.Event('send', {delegatedEvent: e}),
13236                            options
13237                        ) === false) &&
13238                        that._getXHRPromise(false, options.context, aborted)) ||
13239                        that._chunkedUpload(options) || $.ajax(options)
13240                    ).done(function (result, textStatus, jqXHR) {
13241                        that._onDone(result, textStatus, jqXHR, options);
13242                    }).fail(function (jqXHR, textStatus, errorThrown) {
13243                        that._onFail(jqXHR, textStatus, errorThrown, options);
13244                    }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
13245                        that._onAlways(
13246                            jqXHRorResult,
13247                            textStatus,
13248                            jqXHRorError,
13249                            options
13250                        );
13251                        that._sending -= 1;
13252                        that._active -= 1;
13253                        if (options.limitConcurrentUploads &&
13254                                options.limitConcurrentUploads > that._sending) {
13255                            // Start the next queued upload,
13256                            // that has not been aborted:
13257                            var nextSlot = that._slots.shift();
13258                            while (nextSlot) {
13259                                if (that._getDeferredState(nextSlot) === 'pending') {
13260                                    nextSlot.resolve();
13261                                    break;
13262                                }
13263                                nextSlot = that._slots.shift();
13264                            }
13265                        }
13266                        if (that._active === 0) {
13267                            // The stop callback is triggered when all uploads have
13268                            // been completed, equivalent to the global ajaxStop event:
13269                            that._trigger('stop');
13270                        }
13271                    });
13272                    return jqXHR;
13273                };
13274            this._beforeSend(e, options);
13275            if (this.options.sequentialUploads ||
13276                    (this.options.limitConcurrentUploads &&
13277                    this.options.limitConcurrentUploads <= this._sending)) {
13278                if (this.options.limitConcurrentUploads > 1) {
13279                    slot = $.Deferred();
13280                    this._slots.push(slot);
13281                    pipe = slot.then(send);
13282                } else {
13283                    this._sequence = this._sequence.then(send, send);
13284                    pipe = this._sequence;
13285                }
13286                // Return the piped Promise object, enhanced with an abort method,
13287                // which is delegated to the jqXHR object of the current upload,
13288                // and jqXHR callbacks mapped to the equivalent Promise methods:
13289                pipe.abort = function () {
13290                    aborted = [undefined, 'abort', 'abort'];
13291                    if (!jqXHR) {
13292                        if (slot) {
13293                            slot.rejectWith(options.context, aborted);
13294                        }
13295                        return send();
13296                    }
13297                    return jqXHR.abort();
13298                };
13299                return this._enhancePromise(pipe);
13300            }
13301            return send();
13302        },
13303
13304        _onAdd: function (e, data) {
13305            var that = this,
13306                result = true,
13307                options = $.extend({}, this.options, data),
13308                files = data.files,
13309                filesLength = files.length,
13310                limit = options.limitMultiFileUploads,
13311                limitSize = options.limitMultiFileUploadSize,
13312                overhead = options.limitMultiFileUploadSizeOverhead,
13313                batchSize = 0,
13314                paramName = this._getParamName(options),
13315                paramNameSet,
13316                paramNameSlice,
13317                fileSet,
13318                i,
13319                j = 0;
13320            if (!filesLength) {
13321                return false;
13322            }
13323            if (limitSize && files[0].size === undefined) {
13324                limitSize = undefined;
13325            }
13326            if (!(options.singleFileUploads || limit || limitSize) ||
13327                    !this._isXHRUpload(options)) {
13328                fileSet = [files];
13329                paramNameSet = [paramName];
13330            } else if (!(options.singleFileUploads || limitSize) && limit) {
13331                fileSet = [];
13332                paramNameSet = [];
13333                for (i = 0; i < filesLength; i += limit) {
13334                    fileSet.push(files.slice(i, i + limit));
13335                    paramNameSlice = paramName.slice(i, i + limit);
13336                    if (!paramNameSlice.length) {
13337                        paramNameSlice = paramName;
13338                    }
13339                    paramNameSet.push(paramNameSlice);
13340                }
13341            } else if (!options.singleFileUploads && limitSize) {
13342                fileSet = [];
13343                paramNameSet = [];
13344                for (i = 0; i < filesLength; i = i + 1) {
13345                    batchSize += files[i].size + overhead;
13346                    if (i + 1 === filesLength ||
13347                            ((batchSize + files[i + 1].size + overhead) > limitSize) ||
13348                            (limit && i + 1 - j >= limit)) {
13349                        fileSet.push(files.slice(j, i + 1));
13350                        paramNameSlice = paramName.slice(j, i + 1);
13351                        if (!paramNameSlice.length) {
13352                            paramNameSlice = paramName;
13353                        }
13354                        paramNameSet.push(paramNameSlice);
13355                        j = i + 1;
13356                        batchSize = 0;
13357                    }
13358                }
13359            } else {
13360                paramNameSet = paramName;
13361            }
13362            data.originalFiles = files;
13363            $.each(fileSet || files, function (index, element) {
13364                var newData = $.extend({}, data);
13365                newData.files = fileSet ? element : [element];
13366                newData.paramName = paramNameSet[index];
13367                that._initResponseObject(newData);
13368                that._initProgressObject(newData);
13369                that._addConvenienceMethods(e, newData);
13370                result = that._trigger(
13371                    'add',
13372                    $.Event('add', {delegatedEvent: e}),
13373                    newData
13374                );
13375                return result;
13376            });
13377            return result;
13378        },
13379
13380        _replaceFileInput: function (data) {
13381            var input = data.fileInput,
13382                inputClone = input.clone(true),
13383                restoreFocus = input.is(document.activeElement);
13384            // Add a reference for the new cloned file input to the data argument:
13385            data.fileInputClone = inputClone;
13386            $('<form></form>').append(inputClone)[0].reset();
13387            // Detaching allows to insert the fileInput on another form
13388            // without loosing the file input value:
13389            input.after(inputClone).detach();
13390            // If the fileInput had focus before it was detached,
13391            // restore focus to the inputClone.
13392            if (restoreFocus) {
13393                inputClone.focus();
13394            }
13395            // Avoid memory leaks with the detached file input:
13396            $.cleanData(input.unbind('remove'));
13397            // Replace the original file input element in the fileInput
13398            // elements set with the clone, which has been copied including
13399            // event handlers:
13400            this.options.fileInput = this.options.fileInput.map(function (i, el) {
13401                if (el === input[0]) {
13402                    return inputClone[0];
13403                }
13404                return el;
13405            });
13406            // If the widget has been initialized on the file input itself,
13407            // override this.element with the file input clone:
13408            if (input[0] === this.element[0]) {
13409                this.element = inputClone;
13410            }
13411        },
13412
13413        _handleFileTreeEntry: function (entry, path) {
13414            var that = this,
13415                dfd = $.Deferred(),
13416                entries = [],
13417                dirReader,
13418                errorHandler = function (e) {
13419                    if (e && !e.entry) {
13420                        e.entry = entry;
13421                    }
13422                    // Since $.when returns immediately if one
13423                    // Deferred is rejected, we use resolve instead.
13424                    // This allows valid files and invalid items
13425                    // to be returned together in one set:
13426                    dfd.resolve([e]);
13427                },
13428                successHandler = function (entries) {
13429                    that._handleFileTreeEntries(
13430                        entries,
13431                        path + entry.name + '/'
13432                    ).done(function (files) {
13433                        dfd.resolve(files);
13434                    }).fail(errorHandler);
13435                },
13436                readEntries = function () {
13437                    dirReader.readEntries(function (results) {
13438                        if (!results.length) {
13439                            successHandler(entries);
13440                        } else {
13441                            entries = entries.concat(results);
13442                            readEntries();
13443                        }
13444                    }, errorHandler);
13445                };
13446            path = path || '';
13447            if (entry.isFile) {
13448                if (entry._file) {
13449                    // Workaround for Chrome bug #149735
13450                    entry._file.relativePath = path;
13451                    dfd.resolve(entry._file);
13452                } else {
13453                    entry.file(function (file) {
13454                        file.relativePath = path;
13455                        dfd.resolve(file);
13456                    }, errorHandler);
13457                }
13458            } else if (entry.isDirectory) {
13459                dirReader = entry.createReader();
13460                readEntries();
13461            } else {
13462                // Return an empty list for file system items
13463                // other than files or directories:
13464                dfd.resolve([]);
13465            }
13466            return dfd.promise();
13467        },
13468
13469        _handleFileTreeEntries: function (entries, path) {
13470            var that = this;
13471            return $.when.apply(
13472                $,
13473                $.map(entries, function (entry) {
13474                    return that._handleFileTreeEntry(entry, path);
13475                })
13476            ).then(function () {
13477                return Array.prototype.concat.apply(
13478                    [],
13479                    arguments
13480                );
13481            });
13482        },
13483
13484        _getDroppedFiles: function (dataTransfer) {
13485            dataTransfer = dataTransfer || {};
13486            var items = dataTransfer.items;
13487            if (items && items.length && (items[0].webkitGetAsEntry ||
13488                    items[0].getAsEntry)) {
13489                return this._handleFileTreeEntries(
13490                    $.map(items, function (item) {
13491                        var entry;
13492                        if (item.webkitGetAsEntry) {
13493                            entry = item.webkitGetAsEntry();
13494                            if (entry) {
13495                                // Workaround for Chrome bug #149735:
13496                                entry._file = item.getAsFile();
13497                            }
13498                            return entry;
13499                        }
13500                        return item.getAsEntry();
13501                    })
13502                );
13503            }
13504            return $.Deferred().resolve(
13505                $.makeArray(dataTransfer.files)
13506            ).promise();
13507        },
13508
13509        _getSingleFileInputFiles: function (fileInput) {
13510            fileInput = $(fileInput);
13511            var entries = fileInput.prop('webkitEntries') ||
13512                    fileInput.prop('entries'),
13513                files,
13514                value;
13515            if (entries && entries.length) {
13516                return this._handleFileTreeEntries(entries);
13517            }
13518            files = $.makeArray(fileInput.prop('files'));
13519            if (!files.length) {
13520                value = fileInput.prop('value');
13521                if (!value) {
13522                    return $.Deferred().resolve([]).promise();
13523                }
13524                // If the files property is not available, the browser does not
13525                // support the File API and we add a pseudo File object with
13526                // the input value as name with path information removed:
13527                files = [{name: value.replace(/^.*\\/, '')}];
13528            } else if (files[0].name === undefined && files[0].fileName) {
13529                // File normalization for Safari 4 and Firefox 3:
13530                $.each(files, function (index, file) {
13531                    file.name = file.fileName;
13532                    file.size = file.fileSize;
13533                });
13534            }
13535            return $.Deferred().resolve(files).promise();
13536        },
13537
13538        _getFileInputFiles: function (fileInput) {
13539            if (!(fileInput instanceof $) || fileInput.length === 1) {
13540                return this._getSingleFileInputFiles(fileInput);
13541            }
13542            return $.when.apply(
13543                $,
13544                $.map(fileInput, this._getSingleFileInputFiles)
13545            ).then(function () {
13546                return Array.prototype.concat.apply(
13547                    [],
13548                    arguments
13549                );
13550            });
13551        },
13552
13553        _onChange: function (e) {
13554            var that = this,
13555                data = {
13556                    fileInput: $(e.target),
13557                    form: $(e.target.form)
13558                };
13559            this._getFileInputFiles(data.fileInput).always(function (files) {
13560                data.files = files;
13561                if (that.options.replaceFileInput) {
13562                    that._replaceFileInput(data);
13563                }
13564                if (that._trigger(
13565                        'change',
13566                        $.Event('change', {delegatedEvent: e}),
13567                        data
13568                    ) !== false) {
13569                    that._onAdd(e, data);
13570                }
13571            });
13572        },
13573
13574        _onPaste: function (e) {
13575            var items = e.originalEvent && e.originalEvent.clipboardData &&
13576                    e.originalEvent.clipboardData.items,
13577                data = {files: []};
13578            if (items && items.length) {
13579                $.each(items, function (index, item) {
13580                    var file = item.getAsFile && item.getAsFile();
13581                    if (file) {
13582                        data.files.push(file);
13583                    }
13584                });
13585                if (this._trigger(
13586                        'paste',
13587                        $.Event('paste', {delegatedEvent: e}),
13588                        data
13589                    ) !== false) {
13590                    this._onAdd(e, data);
13591                }
13592            }
13593        },
13594
13595        _onDrop: function (e) {
13596            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
13597            var that = this,
13598                dataTransfer = e.dataTransfer,
13599                data = {};
13600            if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
13601                e.preventDefault();
13602                this._getDroppedFiles(dataTransfer).always(function (files) {
13603                    data.files = files;
13604                    if (that._trigger(
13605                            'drop',
13606                            $.Event('drop', {delegatedEvent: e}),
13607                            data
13608                        ) !== false) {
13609                        that._onAdd(e, data);
13610                    }
13611                });
13612            }
13613        },
13614
13615        _onDragOver: getDragHandler('dragover'),
13616
13617        _onDragEnter: getDragHandler('dragenter'),
13618
13619        _onDragLeave: getDragHandler('dragleave'),
13620
13621        _initEventHandlers: function () {
13622            if (this._isXHRUpload(this.options)) {
13623                this._on(this.options.dropZone, {
13624                    dragover: this._onDragOver,
13625                    drop: this._onDrop,
13626                    // event.preventDefault() on dragenter is required for IE10+:
13627                    dragenter: this._onDragEnter,
13628                    // dragleave is not required, but added for c
13628ompleteness:
13629                    dragleave: this._onDragLeave
13630                });
13631                this._on(this.options.pasteZone, {
13632                    paste: this._onPaste
13633                });
13634            }
13635            if ($.support.fileInput) {
13636                this._on(this.options.fileInput, {
13637                    change: this._onChange
13638                });
13639            }
13640        },
13641
13642        _destroyEventHandlers: function () {
13643            this._off(this.options.dropZone, 'dragenter dragleave dragover drop');
13644            this._off(this.options.pasteZone, 'paste');
13645            this._off(this.options.fileInput, 'change');
13646        },
13647
13648        _destroy: function () {
13649            this._destroyEventHandlers();
13650        },
13651
13652        _setOption: function (key, value) {
13653            var reinit = $.inArray(key, this._specialOptions) !== -1;
13654            if (reinit) {
13655                this._destroyEventHandlers();
13656            }
13657            this._super(key, value);
13658            if (reinit) {
13659                this._initSpecialOptions();
13660                this._initEventHandlers();
13661            }
13662        },
13663
13664        _initSpecialOptions: function () {
13665            var options = this.options;
13666            if (options.fileInput === undefined) {
13667                options.fileInput = this.element.is('input[type="file"]') ?
13668                        this.element : this.element.find('input[type="file"]');
13669            } else if (!(options.fileInput instanceof $)) {
13670                options.fileInput = $(options.fileInput);
13671            }
13672            if (!(options.dropZone instanceof $)) {
13673                options.dropZone = $(options.dropZone);
13674            }
13675            if (!(options.pasteZone instanceof $)) {
13676                options.pasteZone = $(options.pasteZone);
13677            }
13678        },
13679
13680        _getRegExp: function (str) {
13681            var parts = str.split('/'),
13682                modifiers = parts.pop();
13683            parts.shift();
13684            return new RegExp(parts.join('/'), modifiers);
13685        },
13686
13687        _isRegExpOption: function (key, value) {
13688            return key !== 'url' && $.type(value) === 'string' &&
13689                /^\/.*\/[igm]{0,3}$/.test(value);
13690        },
13691
13692        _initDataAttributes: function () {
13693            var that = this,
13694                options = this.options,
13695                data = this.element.data();
13696            // Initialize options set via HTML5 data-attributes:
13697            $.each(
13698                this.element[0].attributes,
13699                function (index, attr) {
13700                    var key = attr.name.toLowerCase(),
13701                        value;
13702                    if (/^data-/.test(key)) {
13703                        // Convert hyphen-ated key to camelCase:
13704                        key = key.slice(5).replace(/-[a-z]/g, function (str) {
13705                            return str.charAt(1).toUpperCase();
13706                        });
13707                        value = data[key];
13708                        if (that._isRegExpOption(key, value)) {
13709                            value = that._getRegExp(value);
13710                        }
13711                        options[key] = value;
13712                    }
13713                }
13714            );
13715        },
13716
13717        _create: function () {
13718            this._initDataAttributes();
13719            this._initSpecialOptions();
13720            this._slots = [];
13721            this._sequence = this._getXHRPromise(true);
13722            this._sending = this._active = 0;
13723            this._initProgressObject(this);
13724            this._initEventHandlers();
13725        },
13726
13727        // This method is exposed to the widget API and allows to query
13728        // the number of active uploads:
13729        active: function () {
13730            return this._active;
13731        },
13732
13733        // This method is exposed to the widget API and allows to query
13734        // the widget upload progress.
13735        // It returns an object with loaded, total and bitrate properties
13736        // for the running uploads:
13737        progress: function () {
13738            return this._progress;
13739        },
13740
13741        // This method is exposed to the widget API and allows adding files
13742        // using the fileupload API. The data parameter accepts an object which
13743        // must have a files property and can contain additional options:
13744        // .fileupload('add', {files: filesList});
13745        add: function (data) {
13746            var that = this;
13747            if (!data || this.options.disabled) {
13748                return;
13749            }
13750            if (data.fileInput && !data.files) {
13751                this._getFileInputFiles(data.fileInput).always(function (files) {
13752                    data.files = files;
13753                    that._onAdd(null, data);
13754                });
13755            } else {
13756                data.files = $.makeArray(data.files);
13757                this._onAdd(null, data);
13758            }
13759        },
13760
13761        // This method is exposed to the widget API and allows sending files
13762        // using the fileupload API. The data parameter accepts an object which
13763        // must have a files or fileInput property and can contain additional options:
13764        // .fileupload('send', {files: filesList});
13765        // The method returns a Promise object for the file upload call.
13766        send: function (data) {
13767            if (data && !this.options.disabled) {
13768                if (data.fileInput && !data.files) {
13769                    var that = this,
13770                        dfd = $.Deferred(),
13771                        promise = dfd.promise(),
13772                        jqXHR,
13773                        aborted;
13774                    promise.abort = function () {
13775                        aborted = true;
13776                        if (jqXHR) {
13777                            return jqXHR.abort();
13778                        }
13779                        dfd.reject(null, 'abort', 'abort');
13780                        return promise;
13781                    };
13782                    this._getFileInputFiles(data.fileInput).always(
13783                        function (files) {
13784                            if (aborted) {
13785                                return;
13786                            }
13787                            if (!files.length) {
13788                                dfd.reject();
13789                                return;
13790                            }
13791                            data.files = files;
13792                            jqXHR = that._onSend(null, data);
13793                            jqXHR.then(
13794                                function (result, textStatus, jqXHR) {
13795                                    dfd.resolve(result, textStatus, jqXHR);
13796                                },
13797                                function (jqXHR, textStatus, errorThrown) {
13798                                    dfd.reject(jqXHR, textStatus, errorThrown);
13799                                }
13800                            );
13801                        }
13802                    );
13803                    return this._enhancePromise(promise);
13804                }
13805                data.files = $.makeArray(data.files);
13806                if (data.files.length) {
13807                    return this._onSend(null, data);
13808                }
13809            }
13810            return this._getXHRPromise(false, data && data.context);
13811        }
13812
13813    });
13814
13815}));
13816
13817/*
13818 * jQuery Iframe Transport Plugin
13819 * https://github.com/blueimp/jQuery-File-Upload
13820 *
13821 * Copyright 2011, Sebastian Tschan
13822 * https://blueimp.net
13823 *
13824 * Licensed under the MIT license:
13825 * https://opensource.org/licenses/MIT
13826 */
13827
13828/* global define, require, window, document, JSON */
13829
13830;(function (factory) {
13831    'use strict';
13832    if (typeof define === 'function' && define.amd) {
13833        // Register as an anonymous AMD module:
13834        define(['jquery'], factory);
13835    } else if (typeof exports === 'object') {
13836        // Node/CommonJS:
13837        factory(require('jquery'));
13838    } else {
13839        // Browser globals:
13840        factory(window.jQuery);
13841    }
13842}(function ($) {
13843    'use strict';
13844
13845    // Helper variable to create unique names for the transport iframes:
13846    var counter = 0,
13847        jsonAPI = $,
13848        jsonParse = 'parseJSON';
13849
13850    if ('JSON' in window && 'parse' in JSON) {
13851      jsonAPI = JSON;
13852      jsonParse = 'parse';
13853    }
13854
13855    // The iframe transport accepts four additional options:
13856    // options.fileInput: a jQuery collection of file input fields
13857    // options.paramName: the parameter name for the file form data,
13858    //  overrides the name property of the file input field(s),
13859    //  can be a string or an array of strings.
13860    // options.formData: an array of objects with name and value properties,
13861    //  equivalent to the return data of .serializeArray(), e.g.:
13862    //  [{name: 'a', value: 1}, {name: 'b', value: 2}]
13863    // options.initialIframeSrc: the URL of the initial iframe src,
13864    //  by default set to "javascript:false;"
13865    $.ajaxTransport('iframe', function (options) {
13866        if (options.async) {
13867            // javascript:false as initial iframe src
13868            // prevents warning popups on HTTPS in IE6:
13869            /*jshint scripturl: true */
13870            var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
13871            /*jshint scripturl: false */
13872                form,
13873                iframe,
13874                addParamChar;
13875            return {
13876                send: function (_, completeCallback) {
13877                    form = $('<form style="display:none;"></form>');
13878                    form.attr('accept-charset', options.formAcceptCharset);
13879                    addParamChar = /\?/.test(options.url) ? '&' : '?';
13880                    // XDomainRequest only supports GET and POST:
13881                    if (options.type === 'DELETE') {
13882                        options.url = options.url + addParamChar + '_method=DELETE';
13883                        options.type = 'POST';
13884                    } else if (options.type === 'PUT') {
13885                        options.url = options.url + addParamChar + '_method=PUT';
13886                        options.type = 'POST';
13887                    } else if (options.type === 'PATCH') {
13888                        options.url = options.url + addParamChar + '_method=PATCH';
13889                        options.type = 'POST';
13890                    }
13891                    // IE versions below IE8 cannot set the name property of
13892                    // elements that have already been added to the DOM,
13893                    // so we set the name along with the iframe HTML markup:
13894                    counter += 1;
13895                    iframe = $(
13896                        '<iframe src="' + initialIframeSrc +
13897                            '" name="iframe-transport-' + counter + '"></iframe>'
13898                    ).bind('load', function () {
13899                        var fileInputClones,
13900                            paramNames = $.isArray(options.paramName) ?
13901                                    options.paramName : [options.paramName];
13902                        iframe
13903                            .unbind('load')
13904                            .bind('load', function () {
13905                                var response;
13906                                // Wrap in a try/catch block to catch exceptions thrown
13907                                // when trying to access cross-domain iframe contents:
13908                                try {
13909                                    response = iframe.contents();
13910                                    // Google Chrome and Firefox do not throw an
13911                                    // exception when calling iframe.contents() on
13912                                    // cross-domain requests, so we unify the response:
13913                                    if (!response.length || !response[0].firstChild) {
13914                                        throw new Error();
13915                                    }
13916                                } catch (e) {
13917                                    response = undefined;
13918                                }
13919                                // The complete callback returns the
13920                                // iframe content document as response object:
13921                                completeCallback(
13922                                    200,
13923                                    'success',
13924                                    {'iframe': response}
13925                                );
13926                                // Fix for IE endless progress bar activity bug
13927                                // (happens on form submits to iframe targets):
13928                                $('<iframe src="' + initialIframeSrc + '"></iframe>')
13929                                    .appendTo(form);
13930                                window.setTimeout(function () {
13931                                    // Removing the form in a setTimeout call
13932                                    // allows Chrome's developer tools to display
13933                                    // the response result
13934                                    form.remove();
13935                                }, 0);
13936                            });
13937                        form
13938                            .prop('target', iframe.prop('name'))
13939                            .prop('action', options.url)
13940                            .prop('method', options.type);
13941                        if (options.formData) {
13942                            $.each(options.formData, function (index, field) {
13943                                $('<input type="hidden"/>')
13944                                    .prop('name', field.name)
13945                                    .val(field.value)
13946                                    .appendTo(form);
13947                            });
13948                        }
13949                        if (options.fileInput && options.fileInput.length &&
13950                                options.type === 'POST') {
13951                            fileInputClones = options.fileInput.clone();
13952                            // Insert a clone for each file input field:
13953                            options.fileInput.after(function (index) {
13954                                return fileInputClones[index];
13955                            });
13956                            if (options.paramName) {
13957                                options.fileInput.each(function (index) {
13958                                    $(this).prop(
13959                                        'name',
13960                                        paramNames[index] || options.paramName
13961                                    );
13962                                });
13963                            }
13964                            // Appending the file input fields to the hidden form
13965                            // removes them from their original location:
13966                            form
13967                                .append(options.fileInput)
13968                                .prop('enctype', 'multipart/form-data')
13969                                // enctype must be set as encoding for IE:
13970                                .prop('encoding', 'multipart/form-data');
13971                            // Remove the HTML5 form attribute from the input(s):
13972                            options.fileInput.removeAttr('form');
13973                        }
13974                        form.submit();
13975                        // Insert the file input fields at their original location
13976                        // by replacing the clones with the originals:
13977                        if (fileInputClones && fileInputClones.length) {
13978                            options.fileInput.each(function (index, input) {
13979                                var clone = $(fileInputClones[index]);
13980                                // Restore the original name and form properties:
13981                                $(input)
13982                                    .prop('name', clone.prop('name'))
13983                                    .attr('form', clone.attr('form'));
13984                                clone.replaceWith(input);
13985                            });
13986                        }
13987                    });
13988                    form.append(iframe).appendTo(document.body);
13989                },
13990                abort: function () {
13991                    if (iframe) {
13992                        // javascript:false as iframe src aborts the request
13993                        // and prevents warning popups on HTTPS in IE6.
13994                        // concat is used to avoid the "Script URL" JSLint error:
13995                        iframe
13996                            .unbind('load')
13997                            .prop('src', initialIframeSrc);
13998                    }
13999                    if (form) {
14000                        form.remove();
14001                    }
14002                }
14003            };
14004        }
14005    });
14006
14007    // The iframe transport returns the iframe content document as response.
14008    // The following adds converters from iframe to text, json, html, xml
14009    // and script.
14010    // Please note that the Content-Type for JSON responses has to be text/plain
14011    // or text/html, if the browser doesn't include application/json in the
14012    // Accept header, else IE will show a download dialog.
14013    // The Content-Type for XML responses on the other hand has to be al
14013ways
14014    // application/xml or text/xml, so IE properly parses the XML response.
14015    // See also
14016    // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
14017    $.ajaxSetup({
14018        converters: {
14019            'iframe text': function (iframe) {
14020                return iframe && $(iframe[0].body).text();
14021            },
14022            'iframe json': function (iframe) {
14023                return iframe && jsonAPI[jsonParse]($(iframe[0].body).text());
14024            },
14025            'iframe html': function (iframe) {
14026                return iframe && $(iframe[0].body).html();
14027            },
14028            'iframe xml': function (iframe) {
14029                var xmlDoc = iframe && iframe[0];
14030                return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
14031                        $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
14032                            $(xmlDoc.body).html());
14033            },
14034            'iframe script': function (iframe) {
14035                return iframe && $.globalEval($(iframe[0].body).text());
14036            }
14037        }
14038    });
14039
14040}));
14041
14042/*
14043 Copyright (C) Federico Zivolo 2018
14044 Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
14045 */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=getComputedStyle(e,null);return t?o[t]:o}
vendor: 18,516 bytes, line 14045
14045function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',n=e.nodeName;if('BODY'===n||'HTML'===n){var i=e.ownerDocument.documentElement,r=e.ownerDocument.scrollingElement||i;return r[o]}return e[o]}function f(e,t){var o=2<arguments.length&&void 0!==arguments[2]&&arguments[2],n=l(t,'top'),i=l(t,'left'),r=o?-1:1;return e.top+=n*r,e.bottom+=n*r,e.left+=i*r,e.right+=i*r,e}function m(e,t){var o='x'===t?'Left':'Top',n='Left'==o?'Right':'Bottom';return parseFloat(e['border'+o+'Width'],10)+parseFloat(e['border'+n+'Width'],10)}function h(e,t,o,n){return $(t['offset'+e],t['scroll'+e],o['client'+e],o['offset'+e],o['scroll'+e],r(10)?o['offset'+e]+n['margin'+('Height'===e?'Top':'Left')]+n['margin'+('Height'===e?'Bottom':'Right')]:0)}function c(){var e=document.body,t=document.documentElement,o=r(10)&&getComputedStyle(t);return{height:h('Height',e,t,o),width:h('Width',e,t,o)}}function g(e){return le({},e,{right:e.left+e.width,bottom:e.top+e.height})}function u(e){var o={};try{if(r(10)){o=e.getBoundingClientRect();var n=l(e,'top'),i=l(e,'left');o.top+=n,o.left+=i,o.bottom+=n,o.right+=i}else o=e.getBoundingClientRect()}catch(t){}var p={left:o.left,top:o.top,width:o.right-o.left,height:o.bottom-o.top},s='HTML'===e.nodeName?c():{},d=s.width||e.clientWidth||p.right-p.left,a=s.height||e.clientHeight||p.bottom-p.top,f=e.offsetWidth-d,h=e.offsetHeight-a;if(f||h){var u=t(e);f-=m(u,'x'),h-=m(u,'y'),p.width-=f,p.height-=h}return g(p)}function b(e,o){var i=2<arguments.length&&void 0!==arguments[2]&&arguments[2],p=r(10),s='HTML'===o.nodeName,d=u(e),a=u(o),l=n(e),m=t(o),h=parseFloat(m.borderTopWidth,10),c=parseFloat(m.borderLeftWidth,10);i&&'HTML'===o.nodeName&&(a.top=$(a.top,0),a.left=$(a.left,0));var b=g({top:d.top-a.top-h,left:d.left-a.left-c,width:d.width,height:d.height});if(b.marginTop=0,b.marginLeft=0,!p&&s){var y=parseFloat(m.marginTop,10),w=parseFloat(m.marginLeft,10);b.top-=h-y,b.bottom-=h-y,b.left-=c-w,b.right-=c-w,b.marginTop=y,b.marginLeft=w}return(p&&!i?o.contains(l):o===l&&'BODY'!==l.nodeName)&&(b=f(b,o)),b}function y(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=e.ownerDocument.documentElement,n=b(e,o),i=$(o.clientWidth,window.innerWidth||0),r=$(o.clientHeight,window.innerHeight||0),p=t?0:l(o),s=t?0:l(o,'left'),d={top:p-n.top+n.marginTop,left:s-n.left+n.marginLeft,width:i,height:r};return g(d)}function w(e){var n=e.nodeName;return'BODY'===n||'HTML'===n?!1:'fixed'===t(e,'position')||w(o(e))}function E(e){if(!e||!e.parentElement||r())return document.documentElement;for(var o=e.parentElement;o&&'none'===t(o,'transform');)o=o.parentElement;return o||document.documentElement}function v(e,t,i,r){var p=4<arguments.length&&void 0!==arguments[4]&&arguments[4],s={top:0,left:0},d=p?E(e):a(e,t);if('viewport'===r)s=y(d,p);else{var l;'scrollParent'===r?(l=n(o(t)),'BODY'===l.nodeName&&(l=e.ownerDocument.documentElement)):'window'===r?l=e.ownerDocument.documentElement:l=r;var f=b(l,d,p);if('HTML'===l.nodeName&&!w(d)){var m=c(),h=m.height,g=m.width;s.top+=f.top-f.marginTop,s.bottom=h+f.top,s.left+=f.left-f.marginLeft,s.right=g+f.left}else s=f}return s.left+=i,s.top+=i,s.right-=i,s.bottom-=i,s}function x(e){var t=e.width,o=e.height;return t*o}function O(e,t,o,n,i){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var p=v(o,n,r,i),s={top:{width:p.width,height:t.top-p.top},right:{width:p.right-t.right,height:p.height},bottom:{width:p.width,height:p.bottom-t.bottom},left:{width:t.left-p.left,height:p.height}},d=Object.keys(s).map(function(e){return le({key:e},s[e],{area:x(s[e])})}).sort(function(e,t){return t.area-e.area}),a=d.filter(function(e){var t=e.width,n=e.height;return t>=o.clientWidth&&n>=o.clientHeight}),l=0<a.length?a[0].key:d[0].key,f=e.split('-')[1];return l+(f?'-'+f:'')}function L(e,t,o){var n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,i=n?E(t):a(t,o);return b(o,i,n)}function S(e){var t=getComputedStyle(e),o=parseFloat(t.marginTop)+parseFloat(t.marginBottom),n=parseFloat(t.marginLeft)+parseFloat(t.marginRight),i={width:e.offsetWidth+n,height:e.offsetHeight+o};return i}function T(e){var t={left:'right',right:'left',bottom:'top',top:'bottom'};return e.replace(/left|right|bottom|top/g,function(e){return t[e]})}function C(e,t,o){o=o.split('-')[0];var n=S(e),i={width:n.width,height:n.height},r=-1!==['right','left'].indexOf(o),p=r?'top':'left',s=r?'left':'top',d=r?'height':'width',a=r?'width':'height';return i[p]=t[p]+t[d]/2-n[d]/2,i[s]=o===s?t[s]-n[a]:t[T(s)],i}function D(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function N(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var n=D(e,function(e){return e[t]===o});return e.indexOf(n)}function P(t,o,n){var i=void 0===n?t:t.slice(0,N(t,'name',n));return i.forEach(function(t){t['function']&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var n=t['function']||t.fn;t.enabled&&e(n)&&(o.offsets.popper=g(o.offsets.popper),o.offsets.reference=g(o.offsets.reference),o=n(o,t))}),o}function k(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=L(this.state,this.popper,this.reference,this.options.positionFixed),e.placement=O(this.options.placement,e.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),e.originalPlacement=e.placement,e.positionFixed=this.options.positionFixed,e.offsets.popper=C(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?'fixed':'absolute',e=P(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function W(e,t){return e.some(function(e){var o=e.name,n=e.enabled;return n&&o===t})}function B(e){for(var t=[!1,'ms','Webkit','Moz','O'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function H(){return this.state.isDestroyed=!0,W(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.position='',this.popper.style.top='',this.popper.style.left='',this.popper.style.right='',this.popper.style.bottom='',this.popper.style.willChange='',this.popper.style[B('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function A(e){var t=e.ownerDocument;return t?t.defaultView:window}function M(e,t,o,i){var r='BODY'===e.nodeName,p=r?e.ownerDocument.defaultView:e;p.addEventListener(t,o,{passive:!0}),r||M(n(p.parentNode),t,o,i),i.push(p)}function I(e,t,o,i){o.updateBound=i,A(e).addEventListener('resize',o.updateBound,{passive:!0});var r=n(e);return M(r,'scroll',o.updateBound,o.scrollParents),o.scrollElement=r,o.eventsEnabled=!0,o}function F(){this.state.eventsEnabled||(this.state=I(this.reference,this.options,this.state,this.scheduleUpdate))}function R(e,t){return A(e).removeEventListener('resize',t.updateBound),t.scrollParents.forEach(function(e){e.removeEventListener('scroll',t.updateBound)}),t.updateBound=null,t.scrollParents=[],t.scrollElement=null,t.eventsEnabled=!1,t}function U(){this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=R(this.reference,this.state))}function Y(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function j(e,t){Object.keys(t).forEach(function(o){var n='';-1!==['width','height','top','right','bottom','left'].indexOf(o)&&Y(t[o])&&(n='px'),e.style[o]=t[o]+n})}function K(e,t){Object.keys(t).forEach(function(o){var n=t[o];!1===n?e.removeAttribute(o):e.setAttribute(o,t[o])})}function q(e,t,o){var n=D(e,function(e){var o=e.name;return o===t}),i=!!n&&e.some(function(e){return e.name===o&&e.enabled&&e.order<n.order});if(!i){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return i}function G(e){return'end'===e?'start':'start'===e?'end':e}function z(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=me.indexOf(e),n=me.slice(o+1).concat(me.slice(0,o));return t?n.reverse():n}function V(e,t,o,n){var i=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+i[1],p=i[2];if(!r)return e;if(0===p.indexOf('%')){var s;switch(p){case'%p':s=o;break;case'%':case'%r':default:s=n;}var d=g(s);return d[t]/100*r}if('vh'===p||'vw'===p){var a;return a='vh'===p?$(document.documentElement.clientHeight,window.innerHeight||0):$(document.documentElement.clientWidth,window.innerWidth||0),a/100*r}return r}function _(e,t,o,n){var i=[0,0],r=-1!==['right','left'].indexOf(n),p=e.split(/(\+|\-)/).map(function(e){return e.trim()}),s=p.indexOf(D(p,function(e){return-1!==e.search(/,|\s/)}));p[s]&&-1===p[s].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var d=/\s*,\s*|\s+/,a=-1===s?[p]:[p.slice(0,s).concat([p[s].split(d)[0]]),[p[s].split(d)[1]].concat(p.slice(s+1))];return a=a.map(function(e,n){var i=(1===n?!r:r)?'height':'width',p=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,p=!0,e):p?(e[e.length-1]+=t,p=!1,e):e.concat(t)},[]).map(function(e){return V(e,i,t,o)})}),a.forEach(function(e,t){e.forEach(function(o,n){Y(o)&&(i[t]+=o*('-'===e[n-1]?-1:1))})}),i}function X(e,t){var o,n=t.offset,i=e.placement,r=e.offsets,p=r.popper,s=r.reference,d=i.split('-')[0];return o=Y(+n)?[+n,0]:_(n,p,s,d),'left'===d?(p.top+=o[0],p.left-=o[1]):'right'===d?(p.top+=o[0],p.left+=o[1]):'top'===d?(p.left+=o[0],p.top-=o[1]):'bottom'===d&&(p.left+=o[0],p.top+=o[1]),e.popper=p,e}for(var J=Math.min,Q=Math.round,Z=Math.floor,$=Math.max,ee='undefined'!=typeof window&&'undefined'!=typeof document,te=['Edge','Trident','Firefox'],oe=0,ne=0;ne<te.length;ne+=1)if(ee&&0<=navigator.userAgent.indexOf(te[ne])){oe=1;break}var i=ee&&window.Promise,ie=i?function(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},oe))}},re=ee&&!!(window.MSInputMethodContext&&document.documentMode),pe=ee&&/MSIE 10/.test(navigator.userAgent),se=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},de=function(){function e(e,t){for(var o,n=0;n<t.length;n++)o=t[n],o.enumerable=o.enumerable||!1,o.configurable=!0,'value'in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}return function(t,o,n){return o&&e(t.prototype,o),n&&e(t,n),t}}(),ae=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},le=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var n in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},fe=['auto-start','auto','auto-end','top-start','top','top-end','right-start','right','right-end','bottom-end','bottom','bottom-start','left-end','left','left-start'],me=fe.slice(3),he={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ce=function(){function t(o,n){var i=this,r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};se(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=ie(this.update.bind(this)),this.options=le({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=o&&o.jquery?o[0]:o,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(le({},t.Defaults.modifiers,r.modifiers)).forEach(function(e){i.options.modifiers[e]=le({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return le({name:e},i.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(t){t.enabled&&e(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)}),this.update();var p=this.options.eventsEnabled;p&&this.enableEventListeners(),this.state.eventsEnabled=p}return de(t,[{key:'update',value:function(){return k.call(this)}},{key:'destroy',value:function(){return H.call(this)}},{key:'enableEventListeners',value:function(){return F.call(this)}},{key:'disableEventListeners',value:function(){return U.call(this)}}]),t}();return ce.Utils=('undefined'==typeof window?global:window).PopperUtils,ce.placements=fe,ce.Defaults={placement:'bottom',positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(e){var t=e.placement,o=t.split('-')[0],n=t.split('-')[1];if(n){var i=e.offsets,r=i.reference,p=i.popper,s=-1!==['bottom','top'].indexOf(o),d=s?'left':'top',a=s?'width':'height',l={start:ae({},d,r[d]),end:ae({},d,r[d]+r[a]-p[a])};e.offsets.popper=le({},p,l[n])}return e}},offset:{order:200,enabled:!0,fn:X,offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||p(e.instance.popper);e.instance.reference===o&&(o=p(o));var n=B('transform'),i=e.instance.popper.style,r=i.top,s=i.left,d=i[n];i.top='',i.left='',i[n]='';var a=v(e.instance.popper,e.instance.reference,t.padding,o,e.positionFixed);i.top=r,i.left=s,i[n]=d,t.boundaries=a;var l=t.priority,f=e.offsets.popper,m={primary:function(e){var o=f[e];return f[e]<a[e]&&!t.escapeWithReference&&(o=$(f[e],a[e])),ae({},e,o)},secondary:function(e){var o='right'===e?'left':'top',n=f[o];return f[e]>a[e]&&!t.escapeWithReference&&(n=J(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]<r(n[d])&&(e.offsets.popper[d]=r(n[d])-o[a]),o[d]>r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!q(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-u<s[m]&&(e.offsets.popper[m]-=s[m]-(d[c]-u)),d[m]+u>s[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,y=t(e.instance.popper),w=parseFloat(y['margin'+f],10),E=parseFloat(y['border'+f+'Width'],10),v=b-e.offsets.popper[m]-w-E;return v=$(J(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,Q(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case he.FLIP:p=[n,i];break;case he.CLOCKWISE:p=z(n);break;case he.COUNTERCLOCKWISE:p=z(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)<f(l.right)||'top'===n&&f(a.bottom)>f(l.top)||'bottom'===n&&f(a.top)<f(l.bottom),h=f(a.left)<f(o.left),c=f(a.right)>f(o.right),g=f(a.top)<f(o.top),u=f(a.bottom)>f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,y=-1!==['top','bottom'].indexOf(n),w=!!t.flipVariations&&(y&&'start'===r&&h||y&&'end'===r&&c||!y&&'start'===r&&g||!y&&'end'===r&&u);(m||b||w)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),w&&(r=G(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!q(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottom<o.top||t.left>o.right||t.top>o.bottom||t.right<o.left){if(!0===e.hide)return e;e.hide=!0,e.attributes['x-out-of-boundaries']=''}else{if(!1===e.hide)return e;e.hide=!1,e.attributes['x-out-of-boundaries']=!1}return e}},computeStyle:{order:850,enabled:!0,fn:function(e,t){var o=t.x,n=t.y,i=e.offsets.popper,r=D(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;
14045void 0!==r&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s,d,a=void 0===r?t.gpuAcceleration:r,l=p(e.instance.popper),f=u(l),m={position:i.position},h={left:Z(i.left),top:Q(i.top),bottom:Q(i.bottom),right:Z(i.right)},c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?-f.height+h.bottom:h.top,s='right'==g?-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var y='bottom'==c?-1:1,w='right'==g?-1:1;m[c]=d*y,m[g]=s*w,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return j(e.instance.popper,e.styles),K(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&j(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),j(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ce});
14046
14047
14048var initCaptcha = function(initCaptchaCallback, site_key) {
14049    const container = document.createElement('div');
14050    container.id = 'yandex-captcha-container';
14051    container.setAttribute('style', 'display: none !important');
14052    
14053    // если sng = 1, то это Ближнее Зарубежье
14054    if (typeof GLOBAL === 'undefined' || GLOBAL.sng !== "1") {
14055        container.setAttribute('data-hl', 'en');
14056    }
14057
14058    document.body.appendChild(container);
14059    loadJS('https://smartcaptcha.yandexcloud.net/captcha.js?render=onload&onload=' + initCaptchaCallback);
14060}
14061
14062
14063var renderCaptcha = function(site_key, callback) {
14064    if (!window.smartCaptcha) return;
14065
14066    smartCaptcha.render('yandex-captcha-container', {
14067        sitekey: site_key || GLOBAL.locale.smartcaptcha.site_key,
14068        invisible: true,
14069        hideShield: true,
14070        
14071        hl: (typeof GLOBAL === 'undefined' || GLOBAL.sng !== "1") ? 'en' : 'ru',
14072
14073        callback: callback || function(token) {}
14074    });
14075
14076    smartCaptcha.execute();
14077}
14078
14079var checkCaptchaToken = function(options) {
14080    const type = options.type || 'form';
14081
14082    // Для некоторых сайтов в форме feedback нужно использовать специальный отдельный ключ для feedback
14083    // определяем что форма feedback активна и расширяю type, добавив значение feedback
14084    let effectiveType = type;
14085    if (effectiveType === 'form') {
14086        var visibleFormWithCaptcha = $('form:visible').has('input[name="g-recaptcha-response"]').first();
14087        if ((visibleFormWithCaptcha.attr('id') === 'feedback-form' || visibleFormWithCaptcha.attr('id') === 'feedback-form-privacy') 
14088            && GLOBAL.locale.smartcaptcha.site_key_feedback) {
14089            effectiveType = 'feedback';
14090        }
14091    }
14092/*
14093    const site_key_name = type === 'chat' ? 'site_key_chat' : 'site_key';
14094    const token_name = type === 'chat' ? 'token_chat' : 'token';
14095*/
14096
14097    // Определяем какой ключ использовать
14098    let site_key_name = 'site_key';
14099    let token_name = 'token';
14100    
14101    if (effectiveType === 'chat') {
14102        site_key_name = 'site_key_chat';
14103        token_name = 'token_chat';
14104    } else if (effectiveType === 'feedback' && GLOBAL.locale.smartcaptcha.site_key_feedback) {
14105        site_key_name = 'site_key_feedback';
14106        token_name = 'token_feedback';
14107    }
14108
14109    const captcha = 'smartcaptcha';
14110
14111    if (!GLOBAL.locale[captcha][token_name]) {
14112        const funcName = 'smartcaptcha' + Date.now();
14113
14114        window[ funcName ] = function() {
14115            renderCaptcha(GLOBAL.locale[captcha][site_key_name], function(token) {
14116                GLOBAL.locale[captcha][token_name] = token;
14117                options.callback(token);
14118            });
14119        };
14120
14121        initCaptcha(funcName, GLOBAL.locale[captcha][site_key_name])
14122    } else {
14123        options.callback(GLOBAL.locale[captcha][token_name]);
14124    }
14125}
14126
14127var getTokenReCaptcha = async function() {
14128    return new Promise((resolve) => {
14129        checkCaptchaToken({
14130            callback: function (token) {
14131                resolve(token);
14132            }
14133        });
14134    });
14135}
14136
14137var loadReCaptcha = function() {
14138    checkCaptchaToken({
14139        callback: function (token) {
14140            ria.dispatch('reCaptcha', {token: token, count: 1});
14141
14142            document.querySelectorAll('input[name="g-recaptcha-response"]').forEach(input => {
14143                input.value = token;
14144            });
14145        }
14146    });
14147}
14148
14149/*
14150 * QR Code generator library (JavaScript)
14151 *
14152 * Copyright (c) Project Nayuki. (MIT License)
14153 * https://www.nayuki.io/page/qr-code-generator-library
14154 *
14155 * Permission is hereby granted, free of charge, to any person obtaining a copy of
14156 * this software and associated documentation files (the "Software"), to deal in
14157 * the Software without restriction, including without limitation the rights to
14158 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
14159 * the Software, and to permit persons to whom the Software is furnished to do so,
14160 * subject to the following conditions:
14161 * - The above copyright notice and this permission notice shall be included in
14162 *   all copies or substantial portions of the Software.
14163 * - The Software is provided "as is", without warranty of any kind, express or
14164 *   implied, including but not limited to the warranties of merchantability,
14165 *   fitness for a particular purpose and noninfringement. In no event shall the
14166 *   authors or copyright holders be liable for any claim, damages or other
14167 *   liability, whether in an action of contract, tort or otherwise, arising from,
14168 *   out of or in connection with the Software or the use or other dealings in the
14169 *   Software.
14170 */
14171
14172"use strict";
14173
14174
14175/*
14176 * Module "qrcodegen", public members:
14177 * - Class QrCode:
14178 *   - Function encodeText(str text, QrCode.Ecc ecl) -> QrCode
14179 *   - Function encodeBinary(list<byte> data, QrCode.Ecc ecl) -> QrCode
14180 *   - Function encodeSegments(list<QrSegment> segs, QrCode.Ecc ecl,
14181 *         int minVersion=1, int maxVersion=40, mask=-1, boostEcl=true) -> QrCode
14182 *   - Constants int MIN_VERSION, MAX_VERSION
14183 *   - Constructor QrCode(list<int> datacodewords, int mask, int version, QrCode.Ecc ecl)
14184 *   - Fields int version, size, mask
14185 *   - Field QrCode.Ecc errorCorrectionLevel
14186 *   - Method getModule(int x, int y) -> bool
14187 *   - Method drawCanvas(int scale, int border, HTMLCanvasElement canvas) -> void
14188 *   - Method toSvgString(int border) -> str
14189 *   - Enum Ecc:
14190 *     - Constants LOW, MEDIUM, QUARTILE, HIGH
14191 *     - Field int ordinal
14192 * - Class QrSegment:
14193 *   - Function makeBytes(list<int> data) -> QrSegment
14194 *   - Function makeNumeric(str data) -> QrSegment
14195 *   - Function makeAlphanumeric(str data) -> QrSegment
14196 *   - Function makeSegments(str text) -> list<QrSegment>
14197 *   - Function makeEci(int assignVal) -> QrSegment
14198 *   - Constructor QrSegment(QrSegment.Mode mode, int numChars, list<int> bitData)
14199 *   - Field QrSegment.Mode mode
14200 *   - Field int numChars
14201 *   - Method getBits() -> list<int>
14202 *   - Constants RegExp NUMERIC_REGEX, ALPHANUMERIC_REGEX
14203 *   - Enum Mode:
14204 *     - Constants NUMERIC, ALPHANUMERIC, BYTE, KANJI, ECI
14205 */
14206var qrcodegen = new function() {
14207
14208	/*---- QR Code symbol class ----*/
14209
14210	/*
14211	 * A class that represents an immutable square grid of black and white cells for a QR Code symbol,
14212	 * with associated static functions to create a QR Code from user-supplied textual or binary data.
14213	 * This class covers the QR Code model 2 specification, supporting all versions (sizes)
14214	 * from 1 to 40, all 4 error correction levels.
14215	 * This constructor creates a new QR Code symbol with the given version number, error correction level, binary data array,
14216	 * and mask number. mask = -1 is for automatic choice, or 0 to 7 for fixed choice. This is a cumbersome low-level constructor
14217	 * that should not be invoked directly by the user. To go one level up, see the QrCode.encodeSegments() function.
14218	 */
14219	this.QrCode = function(datacodewords, mask, version, errCorLvl) {
14220
14221		/*---- Constructor ----*/
14222
14223		// Check arguments and handle simple scalar fields
14224		if (mask < -1 || mask > 7)
14225			throw "Mask value out of range";
14226		if (version < MIN_VERSION || version > MAX_VERSION)
14227			throw "Version value out of range";
14228		var size = version * 4 + 17;
14229
14230		// Initialize both grids to be size*size arrays of Boolean false
14231		var row = [];
14232		for (var i = 0; i < size; i++)
14233			row.push(false);
14234		var modules = [];
14235		var isFunction = [];
14236		for (var i = 0; i < size; i++) {
14237			modules.push(row.slice());
14238			isFunction.push(row.slice());
14239		}
14240
14241		// Handle grid fields, draw function patterns, draw all codewords
14242		drawFunctionPatterns();
14243		var allCodewords = appendErrorCorrection(datacodewords);
14244		drawCodewords(allCodewords);
14245
14246		// Handle masking
14247		if (mask == -1) {  // Automatically choose best mask
14248			var minPenalty = Infinity;
14249			for (var i = 0; i < 8; i++) {
14250				drawFormatBits(i);
14251				applyMask(i);
14252				var penalty = getPenaltyScore();
14253				if (penalty < minPenalty) {
14254					mask = i;
14255					minPenalty = penalty;
14256				}
14257				applyMask(i);  // Undoes the mask due to XOR
14258			}
14259		}
14260		if (mask < 0 || mask > 7)
14261			throw "Assertion error";
14262		drawFormatBits(mask);  // Overwrite old format bits
14263		applyMask(mask);  // Apply the final choice of mask
14264
14265
14266		/*---- Read-only instance properties ----*/
14267
14268		// This QR Code symbol's version number, which is always between 1 and 40 (inclusive).
14269		Object.defineProperty(this, "version", {value:version});
14270
14271		// The width and height of this QR Code symbol, measured in modules.
14272		// Always equal to version * 4 + 17, in the range 21 to 177.
14273		Object.defineProperty(this, "size", {value:size});
14274
14275		// The error correction level used in this QR Code symbol.
14276		Object.defineProperty(this, "errorCorrectionLevel", {value:errCorLvl});
14277
14278		// The mask pattern used in this QR Code symbol, in the range 0 to 7 (i.e. unsigned 3-bit integer).
14279		// Note that even if the constructor was called with automatic masking requested
14280		// (mask = -1), the resulting object will still have a mask value between 0 and 7.
14281		Object.defineProperty(this, "mask", {value:mask});
14282
14283
14284		/*---- Accessor methods ----*/
14285
14286		// (Public) Returns the color of the module (pixel) at the given coordinates, which is either
14287		// false for white or true for black. The top left corner has the coordinates (x=0, y=0).
14288		// If the given coordinates are out of bounds, then false (white) is returned.
14289		this.getModule = function(x, y) {
14290			return 0 <= x && x < size && 0 <= y && y < size && modules[y][x];
14291		};
14292
14293		// (Package-private) Tests whether the module at the given coordinates is a function module (true) or not (false).
14294		// The top left corner has the coordinates (x=0, y=0). If the given coordinates are out of bounds, then false is returned.
14295		// The JavaScript version of this library has this method because it is impossible to access private variables of another object.
14296		this.isFunctionModule = function(x, y) {
14297			if (0 <= x && x < size && 0 <= y && y < size)
14298				return isFunction[y][x];
14299			else
14300				return false;  // Infinite border
14301		};
14302
14303
14304		/*---- Public instance methods ----*/
14305
14306		// Draws this QR Code symbol with the given module scale and number of modules onto the given HTML canvas element.
14307		// The canvas will be resized to a width and height of (this.size + border * 2) * scale. The painted image will be purely
14308		// black and white with no transparent regions. The scale must be a positive integer, and the border must be a non-negative integer.
14309		this.drawCanvas = function(scale, border, canvas) {
14310			if (scale <= 0 || border < 0)
14311				throw "Value out of range";
14312			var width = (size + border * 2) * scale;
14313			canvas.width = width;
14314			canvas.height = width;
14315			var ctx = canvas.getContext("2d");
14316			for (var y = -border; y < size + border; y++) {
14317				for (var x = -border; x < size + border; x++) {
14318					ctx.fillStyle = this.getModule(x, y) ? "#000000" : "#FFFFFF";
14319					ctx.fillRect((x + border) * scale, (y + border) * scale, scale, scale);
14320				}
14321			}
14322		};
14323
14324		// Based on the given number of border modules to add as padding, this returns a
14325		// string whose contents represents an SVG XML file that depicts this QR Code symbol.
14326		// Note that Unix newlines (\n) are always used, regardless of the platform.
14327		this.toSvgString = function(border) {
14328			if (border < 0)
14329				throw "Border must be non-negative";
14330			var result = '<?xml version="1.0" encoding="UTF-8"?>\n';
14331			result += '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n';
14332			result += '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 ' +
14333				(size + border * 2) + ' ' + (size + border * 2) + '" stroke="none">\n';
14334			result += '\t<rect width="100%" height="100%" fill="#FFFFFF"/>\n';
14335			result += '\t<path d="';
14336			var head = true;
14337			for (var y = -border; y < size + border; y++) {
14338				for (var x = -border; x < size + border; x++) {
14339					if (this.getModule(x, y)) {
14340						if (head)
14341							head = false;
14342						else
14343							result += " ";
14344						result += "M" + (x + border) + "," + (y + border) + "h1v1h-1z";
14345					}
14346				}
14347			}
14348			result += '" fill="#000000"/>\n';
14349			result += '</svg>\n';
14350			return result;
14351		};
14352
14353
14354		/*---- Private helper methods for constructor: Drawing function modules ----*/
14355
14356		function drawFunctionPatterns() {
14357			// Draw horizontal and vertical timing patterns
14358			for (var i = 0; i < size; i++) {
14359				setFunctionModule(6, i, i % 2 == 0);
14360				setFunctionModule(i, 6, i % 2 == 0);
14361			}
14362
14363			// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
14364			drawFinderPattern(3, 3);
14365			drawFinderPattern(size - 4, 3);
14366			drawFinderPattern(3, size - 4);
14367
14368			// Draw numerous alignment patterns
14369			var alignPatPos = QrCode.getAlignmentPatternPositions(version);
14370			var numAlign = alignPatPos.length;
14371			for (var i = 0; i < numAlign; i++) {
14372				for (var j = 0; j < numAlign; j++) {
14373					if (i == 0 && j == 0 || i == 0 && j == numAlign - 1 || i == numAlign - 1 && j == 0)
14374						continue;  // Skip the three finder corners
14375					else
14376						drawAlignmentPattern(alignPatPos[i], alignPatPos[j]);
14377				}
14378			}
14379
14380			// Draw configuration data
14381			drawFormatBits(0);  // Dummy mask value; overwritten later in the constructor
14382			drawVersion();
14383		}
14384
14385
14386		// Draws two copies of the format bits (with its own error correction code)
14387		// based on the given mask and this object's error correction level field.
14388		function drawFormatBits(mask) {
14389			// Calculate error correction code and pack bits
14390			var data = errCorLvl.formatBits << 3 | mask;  // errCorrLvl is uint2, mask is uint3
14391			var rem = data;
14392			for (var i = 0; i < 10; i++)
14393				rem = (rem << 1) ^ ((rem >>> 9) * 0x537);
14394			data = data << 10 | rem;
14395			data ^= 0x5412;  // uint15
14396			if (data >>> 15 != 0)
14397				throw "Assertion error";
14398
14399			// Draw first copy
14400			for (var i = 0; i <= 5; i++)
14401				setFunctionModule(8, i, getBit(data, i));
14402			setFunctionModule(8, 7, getBit(data, 6));
14403			setFunctionModule(8, 8, getBit(data, 7));
14404			setFunctionModule(7, 8, getBit(data, 8));
14405			for (var i = 9; i < 15; i++)
14406				setFunctionModule(14 - i, 8, getBit(data, i));
14407
14408			// Draw second copy
14409			for (var i = 0; i <= 7; i++)
14410				setFunctionModule(size - 1 - i, 8, getBit(data, i));
14411			for (var i = 8; i < 15; i++)
14412				setFunctionModule(8, size - 15 + i, getBit(data, i));
14413			setFunctionModule(8, size - 8, true);
14414		}
14415
14416
14417		// Draws two copies of the version bits (with its own error correction code),
14418		// based on this object's version field (which only has an effect for 7 <= version <= 40).
14419		function drawVersion() {
14420			if (version < 7)
14421				return;
14422
14423			// Calculate error correction code and pack bits
14424			var rem = version;  // version is uint6, in the range [7, 40]
14425			for (var i = 0; i < 12; i++)
14426				rem = (rem << 1) ^ ((rem >>> 11) * 0x1F25);
14427			var data = version << 12 | rem;  // uint18
14428			if (data >>> 18 != 0)
14429				throw "Assertion error";
14430
14431			// Draw two copies
14432			for (var i = 0; i < 18; i++) {
14433				var bit = getBit(data, i);
14434				var a = size - 11 + i % 3, b = Math.floor(i / 3);
14435				setFunctionModule(a, b, bit);
14436				setFunctionModule(b, a, bit);
14437			}
14438		}
14439
14440
14441		// Draws a 9*9 finder pattern including the border separator, with the center module at (x, y).
14442		function drawFinderPattern(x, y) {
14443			for (var i = -4; i <= 4; i++) {
14444				for (var j = -4; j <= 4; j++) {
14445					var dist = Math.max(Math.abs(i), Math.abs(j));  // Chebyshev/infinity norm
14446					var xx = x + j, yy = y + i;
14447					if (0 <= xx && xx < size && 0 <= yy && yy < size)
14448						setFunctionModule(xx, yy, dist != 2 && dist != 4);
14449				}
14450			}
14451		}
14452
14453
14454		// Draws a 5*5 alignment pattern, with the center module at (x, y).
14455		function drawAlignmentPattern(x, y) {
14456			for (var i = -2; i <= 2; i++) {
14457				for (var j = -2; j <= 2; j++)
14458					setFunctionModule(x + j, y + i, Math.max(Math.abs(i), Math.abs(j)) != 1);
14459			}
14460		}
14461
14462
14463		// Sets the color of a module and marks it as a function module.
14464		// Only used by the constructor. Coordinates must be in range.
14465		function setFunctionModule(x, y, isBlack) {
14466			modules[y][x] = isBlack;
14467			isFunction[y][x] = true;
14468		}
14469
14470
14471		/*---- Private helper methods for constructor: Codewords and masking ----*/
14472
14473		// Returns a new byte string representing the given data with the appropriate error correction
14474		// codewords appended to it, based on this object's version and error correction level.
14475		function appendErrorCorrection(data) {
14476			if (data.length != QrCode.getNumDataCodewords(version, errCorLvl))
14477				throw "Invalid argument";
14478
14479			// Calculate parameter numbers
14480			var numBlocks = QrCode.NUM_ERROR_CORRECTION_BLOCKS[errCorLvl.ordinal][version];
14481			var blockEccLen = QrCode.ECC_CODEWORDS_PER_BLOCK[errCorLvl.ordinal][version];
14482			var rawCodewords = Math.floor(QrCode.getNumRawDataModules(version) / 8);
14483			var numShortBlocks = numBlocks - rawCodewords % numBlocks;
14484			var shortBlockLen = Math.floor(rawCodewords / numBlocks);
14485
14486			// Split data into blocks and append ECC to each block
14487			var blocks = [];
14488			var rs = new ReedSolomonGenerator(blockEccLen);
14489			for (var i = 0, k = 0; i < numBlocks; i++) {
14490				var dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));
14491				k += dat.length;
14492				var ecc = rs.getRemainder(dat);
14493				if (i < numShortBlocks)
14494					dat.push(0);
14495				ecc.forEach(function(b) {
14496					dat.push(b);
14497				});
14498				blocks.push(dat);
14499			}
14500
14501			// Interleave (not concatenate) the bytes from every block into a single sequence
14502			var result = [];
14503			for (var i = 0; i < blocks[0].length; i++) {
14504				for (var j = 0; j < blocks.length; j++) {
14505					// Skip the padding byte in short blocks
14506					if (i != shortBlockLen - blockEccLen || j >= numShortBlocks)
14507						result.push(blocks[j][i]);
14508				}
14509			}
14510			if (result.length != rawCodewords)
14511				throw "Assertion error";
14512			return result;
14513		}
14514
14515
14516		// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
14517		// data area of this QR Code symbol. Function modules need to be marked off before this is called.
14518		function drawCodewords(data) {
14519			if (data.length != Math.floor(QrCode.getNumRawDataModules(version) / 8))
14520				throw "Invalid argument";
14521			var i = 0;  // Bit index into the data
14522			// Do the funny zigzag scan
14523			for (var right = size - 1; right >= 1; right -= 2) {  // Index of right column in each column pair
14524				if (right == 6)
14525					right = 5;
14526				for (var vert = 0; vert < size; vert++) {  // Vertical counter
14527					for (var j = 0; j < 2; j++) {
14528						var x = right - j;  // Actual x coordinate
14529						var upward = ((right + 1) & 2) == 0;
14530						var y = upward ? size - 1 - vert : vert;  // Actual y coordinate
14531						if (!isFunction[y][x] && i < data.length * 8) {
14532							modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));
14533							i++;
14534						}
14535						// If there are any remainder bits (0 to 7), they are already
14536						// set to 0/false/white when the grid of modules was initialized
14537					}
14538				}
14539			}
14540			if (i != data.length * 8)
14541				throw "Assertion error";
14542		}
14543
14544
14545		// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical
14546		// properties, calling applyMask(m) twice with the same value is equivalent to no change at all.
14547		// This means it is possible to apply a mask, undo it, and try another mask. Note that a final
14548		// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.).
14549		function applyMask(mask) {
14550			if (mask < 0 || mask > 7)
14551				throw "Mask value out of range";
14552			for (var y = 0; y < size; y++) {
14553				for (var x = 0; x < size; x++) {
14554					var invert;
14555					switch (mask) {
14556						case 0:  invert = (x + y) % 2 == 0;                                  break;
14557						case 1:  invert = y % 2 == 0;                                        break;
14558						case 2:  invert = x % 3 == 0;                                        break;
14559						case 3:  invert = (x + y) % 3 == 0;                                  break;
14560						case 4:  invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 == 0;  break;
14561						case 5:  invert = x * y % 2 + x * y % 3 == 0;                        break;
14562						case 6:  invert = (x * y % 2 + x * y % 3) % 2 == 0;                  break;
14563						case 7:  invert = ((x + y) % 2 + x * y % 3) % 2 == 0;                break;
14564						default:  throw "Assertion error";
14565					}
14566					modules[y][x] ^= invert & !isFunction[y][x];
14567				}
14568			}
14569		}
14570
14571
14572		// Calculates and returns the penalty score based on state of this QR Code's current modules.
14573		// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
14574		function getPenaltyScore() {
14575			var result = 0;
14576
14577			// Adjacent modules in row having same color
14578			for (var y = 0; y < size; y++) {
14579				for (var x = 0, runX, colorX; x < size; x++) {
14580					if (x == 0 || modules[y][x] != colorX) {
14581						colorX = modules[y][x];
14582						runX = 1;
14583					} else {
14584						runX++;
14585						if (runX == 5)
14586							result += QrCode.PENALTY_N1;
14587						else if (runX > 5)
14588							result++;
14589					}
14590				}
14591			}
14592			// Adjacent modules in column having same color
14593			for (var x = 0; x < size; x++) {
14594				for (var y = 0, runY, colorY; y < size; y++) {
14595					if (y == 0 || modules[y][x] != colorY) {
14596						colorY = modules[y][x];
14597						runY = 1;
14598					} else {
14599						runY++;
14600						if (runY == 5)
14601							result += QrCode.PENALTY_N1;
14602						else if (runY > 5)
14603							result++;
14604					}
14605				}
14606			}
14607
14608			// 2*2 blocks of modules having same color
14609			for (var y = 0; y < size - 1; y++) {
14610				for (var x = 0; x < size - 1; x++) {
14611					var   color = modules[y][x];
14612					if (  color == modules[y][x + 1] &&
14613						color == modules[y + 1][x] &&
14614						color == modules[y + 1][x + 1])
14615						result += QrCode.PENALTY_N2;
14616				}
14617			}
14618
14619			// Finder-like pattern in rows
14620			for (var y = 0; y < size; y++) {
14621				for (var x = 0, bits = 0; x < size; x++) {
14622					bits = ((bits << 1) & 0x7FF) | (modules[y][x] ? 1 : 0);
14623					if (x >= 10 && (bits == 0x05D || bits == 0x5D0))  // Needs 11 bits accumulated
14624						result += QrCode.PENALTY_N3;
14625				}
14626			}
14627			// Finder-like pattern in columns
14628			for (var x = 0; x < size; x++) {
14629				for (var y = 0, bits = 0; y < size; y++) {
14630					bits = ((bits << 1) & 0x7FF) | (modules[y][x] ? 1 : 0);
14631					if (y >= 10 && (bits == 0x05D || bits == 0x5D0))  // Needs 11 bits accumulated
14632						result += QrCode.PENALTY_N3;
14633				}
14634			}
14635
14636			// Balance of black and white modules
14637			var black = 0;
14638			modules.forEach(function(row) {
14639				row.forEach(function(color) {
14640					if (color)
14641						black++;
14642				});
14643			});
14644			var total = size * size;
14645			// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
14646			for (var k = 0; black*20 < (9-k)*total || black*20 > (11+k)*total; k++)
14647				result += QrCode.PENALTY_N4;
14648			return result;
14649		}
14650
14651
14652		// Returns true iff the i'th bit of x is set to 1.
14653		function getBit(x, i) {
14654			return ((x >>> i) & 1) != 0;
14655		}
14656	};
14657
14658
14659	/*---- Public static factory functions for QrCode ----*/
14660
14661	/*
14662	 * Returns a QR Code symbol representing the specified Unicode text string at the specified error correction level.
14663	 * As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer
14664	 * Unicode code points (not UTF-16 code units) if the low error correction level is used. The smallest possible
14665	 * QR Code version is automatically chosen for the output. The ECC level of the result may be higher than the
14666	 * ecl argument if it can be done without increasing the version.
14667	 */
14668	this.QrCode.encodeText = function(text, ecl) {
14669		var segs = qrcodegen.QrSegment.makeSegments(text);
14670		return this.encodeSegments(segs, ecl);
14671	};
14672
14673
14674	/*
14675	 * Returns a QR Code symbol representing the given binary data string at the given error correction level.
14676	 * This function always encodes using the binary segment mode, not any text mode. The maximum number of
14677	 * bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
14678	 * The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
14679	 */
14680	this.QrCode.encodeBinary = function(data, ecl) {
14681		var seg = qrcodegen.QrSegment.makeBytes(data);
14682		return this.encodeSegments([seg], ecl);
14683	};
14684
14685
14686	/*
14687	 * Returns a QR Code symbol representing the given data segments with the given encoding parameters.
14688	 * The smallest possible QR Code version within the given range is automatically chosen for the output.
14689	 * This function allows the user to create a custom sequence of segments that switches
14690	 * between modes (such as alphanumeric and binary) to encode text more efficiently.
14691	 * This function is considered to be lower level than simply encoding text or binary data.
14692	 */
14693	this.QrCode.encodeSegments = function(segs, ecl, minVersion, maxVersion, mask, boostEcl) {
14694		if (minVersion == undefined) minVersion = MIN_VERSION;
14695		if (maxVersion == undefined) maxVersion = MAX_VERSION;
14696		if (mask == undefined) mask = -1;
14697		if (boostEcl == undefined) boostEcl = true;
14698		if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
14699			throw "Invalid value";
14700
14701		// Find the minimal version number to use
14702		var version, dataUsedBits;
14703		for (version = minVersion; ; version++) {
14704			var dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8;  // Number of data bits available
14705			dataUsedBits = qrcodegen.QrSegment.getTotalBits(segs, version);
14706			if (dataUsedBits != null && dataUsedBits <= dataCapacityBits)
14707				break;  // This version number is found to be suitable
14708			if (version >= maxVersion)  // All versions in the range could not fit the given data
14709				throw "Data too long";
14710		}
14711
14712		// Increase the error correction level while the data still fits in the current version number
14713		[this.Ecc.MEDIUM, this.Ecc.QUARTILE, this.Ecc.HIGH].forEach(function(newEcl) {
14714			if (boostEcl && dataUsedBits <= QrCode.getNumDataCodewords(version, newEcl) * 8)
14715				ecl = newEcl;
14716		});
14717
14718		// Create the data bit string by concatenating all segments
14719		var dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8;
14720		var bb = new BitBuffer();
14721		segs.forEach(function(seg) {
14722			bb.appendBits(seg.mode.modeBits, 4);
14723			bb.appendBits(seg.numChars, seg.mode.numCharCountBits(version));
14724			seg.getBits().forEach(function(bit) {
14725				bb.push(bit);
14726			});
14727		});
14728
14729		// Add terminator and pad up to a byte if applicable
14730		bb.appendBits(0, Math.min(4, dataCapacityBits - bb.length));
14731		bb.appendBits(0, (8 - bb.length % 8) % 8);
14732
14733		// Pad with alternate bytes until data capacity is reached
14734		for (var padByte = 0xEC; bb.length < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
14735			bb.appendBits(padByte, 8);
14736		if (bb.length % 8 != 0)
14737			throw "Assertion error";
14738
14739		// Create the QR Code symbol
14740		return new this(bb.getBytes(), mask, version, ecl);
14741	};
14742
14743
14744	/*---- Public constants for QrCode ----*/
14745
14746	var MIN_VERSION =  1;
14747	var MAX_VERSION = 40;
14748	Object.defineProperty(this.QrCode, "MIN_VERSION", {value:MIN_VERSION});
14749	Object.defineProperty(this.QrCode, "MAX_VERSION", {value:MAX_VERSION});
14750
14751
14752	/*---- Private static helper functions QrCode ----*/
14753
14754	var QrCode = {};  // Private object to assign properties to. Not the same object as 'this.QrCode'.
14755
14756
14757	// Returns a sequence of positions of the alignment patterns in ascending order. These positions are
14758	// used on both the x and y axes. Each value in the resulting sequence is in the range [0, 177).
14759	// This stateless pure function could be implemented as table of 40 variable-length lists of integers.
14760	QrCode.getAlignmentPatternPositions = function(ver) {
14761		if (ver < MIN_VERSION || ver > MAX_VERSION)
14762			throw "Version number out of range";
14763		else if (ver == 1)
14764			return [];
14765		else {
14766			var size = ver * 4 + 17;
14767			var numAlign = Math.floor(ver / 7) + 2;
14768			var step;
14769			if (ver != 32)
14770				step = Math.ceil((size - 13) / (2 * numAlign - 2)) * 2;
14771			else  // C-C-C-Combo breaker!
14772				step = 26;
14773
14774			var result = [6];
14775			for (var i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step)
14776				result.splice(1, 0, pos);
14777			return result;
14778		}
14779	};
14780
14781
14782	// Returns the number of data bits that can be stored in a QR Code of the given version number, after
14783	// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
14784	// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
14785	QrCode.getNumRawDataModules = function(ver) {
14786		if (ver < MIN_VERSION || ver > MAX_VERSION)
14787			throw "Version number out of range";
14788		var result = (16 * ver + 128) * ver + 64;
14789		if (ver >= 2) {
14790			var numAlign = Math.floor(ver / 7) + 2;
14791			result -= (25 * numAlign - 10) * numAlign - 55;
14792			if (ver >= 7)
14793				result -= 18 * 2;  // Subtract version information
14794		}
14795		return result;
14796	};
14797
14798
14799	// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
14800	// QR Code of the given version number and error correction level, with remainder bits discarded.
14801	// This stateless pure function could be implemented as a (40*4)-cell lookup table.
14802	QrCode.getNumDataCodewords = function(ver, ecl) {
14803		if (ver < MIN_VERSION || ver > MAX_VERSION)
14804			throw "Version number out of range";
14805		return Math.floor(QrCode.getNumRawDataModules(ver) / 8) -
14806			QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] *
14807			QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];
14808	};
14809
14810
14811	/*---- Private tables of constants for QrCode ----*/
14812
14813	// For use in getPenaltyScore(), when evaluating which mask is best.
14814	QrCode.PENALTY_N1 = 3;
14815	QrCode.PENALTY_N2 = 3;
14816	QrCode.PENALTY_N3 = 40;
14817	QrCode.PENALTY_N4 = 10;
14818
14819	QrCode.ECC_CODEWORDS_PER_BLOCK = [
14820		// Version: (note that index 0 is for padding, and is set to an illegal value)
14821		//  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
14822		[null,  7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // Low
14823		[null, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28],  // Medium
14824		[null, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // Quartile
14825		[null, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // High
14826	];
14827
14828	QrCode.NUM_ERROR_CORRECTION_BLOCKS = [
14829		// Version: (note that index 0 is for padding, and is set to an illegal value)
14830		//  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
14831		[null, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4,  4,  4,  4,  4,  6,  6,  6,  6,  7,  8,  8,  9,  9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25],  // Low
14832		[null, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5,  5,  8,  9,  9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49],  // Medium
14833		[null, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8,  8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68],  // Quartile
14834		[null, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81],  // High
14835	];
14836
14837
14838	/*---- Public helper enumeration ----*/
14839
14840	/*
14841	 * Represents the error correction level used in a QR Code symbol.
14842	 */
14843	this.QrCode.Ecc = {
14844		// Constants declared in ascending order of error protection
14845		LOW     : new Ecc(0, 1),
14846		MEDIUM  : new Ecc(1, 0),
14847		QUARTILE: new Ecc(2, 3),
14848		HIGH    : new Ecc(3, 2),
14849	};
14850
14851
14852	// Private constructor.
14853	function Ecc(ord, fb) {
14854		// (Public) In the range 0 to 3 (unsigned 2-bit integer)
14855		Object.defineProperty(this, "ordinal", {value:ord});
14856
14857		// (Package-private) In the range 0 to 3 (unsigned 2-bit integer)
14858		Object.defineProperty(this, "formatBits", {value:fb});
14859	}
14860
14861
14862
14863	/*---- Data segment class ----*/
14864
14865	/*
14866	 * A public class that represents a character string to be encoded in a QR Code symbol.
14867	 * Each segment has a mode, and a sequence of characters that is already encoded as
14868	 * a sequence of bits. Instances of this class are immutable.
14869	 * This segment class imposes no length restrictions, but QR Codes have restrictions.
14870	 * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
14871	 * Any segment longer than this is meaningless for the purpose of generating QR Codes.
14872	 */
14873	this.QrSegment = function(mode, numChars, bitData) {
14874		if (numChars < 0 || !(mode instanceof Mode))
14875			throw "Invalid argument";
14876		bitData = bitData.slice();  // Make defensive copy
14877
14878		// The mode indicator for this segment.
14879		Object.defineProperty(this, "mode", {value:mode});
14880
14881		// The length of this segment's unencoded data, measured in characters. Always zero or positive.
14882		Object.defineProperty(this, "numChars", {value:numChars});
14883
14884		// Returns a copy of all bits, which is an array of 0s and 1s.
14885		this.getBits = function() {
14886			return bitData.slice();  // Make defensive copy
14887		};
14888	};
14889
14890
14891	/*---- Public static factory functions for QrSegment ----*/
14892
14893	/*
14894	 * Returns a segment representing the given binary data encoded in byte mode.
14895	 */
14896	this.QrSegment.makeBytes = function(data) {
14897		var bb = new BitBuffer();
14898		data.forEach(function(b) {
14899			bb.appendBits(b, 8);
14900		});
14901		return new this(this.Mode.BYTE, data.length, bb);
14902	};
14903
14904
14905	/*
14906	 * Returns a segment representing the given string of decimal digits encoded in numeric mode.
14907	 */
14908	this.QrSegment.makeNumeric = function(digits) {
14909		if (!this.NUMERIC_REGEX.test(digits))
14910			throw "String contains non-numeric characters";
14911		var bb = new BitBuffer();
14912		var i;
14913		for (i = 0; i + 3 <= digits.length; i += 3)  // Process groups of 3
14914			bb.appendBits(parseInt(digits.substr(i, 3), 10), 10);
14915		var rem = digits.length - i;
14916		if (rem > 0)  // 1 or 2 digits remaining
14917			bb.appendBits(parseInt(digits.substring(i), 10), rem * 3 + 1);
14918		return new this(this.Mode.NUMERIC, digits.length, bb);
14919	};
14920
14921
14922	/*
14923	 * Returns a segment representing the given text string encoded in alphanumeric mode.
14924	 * The characters allowed are: 0 to 9, A to Z (uppercase only), space,
14925	 * dollar, percent, asterisk, plus, hyphen, period, slash, colon.
14926	 */
14927	this.QrSegment.makeAlphanumeric = function(text) {
14928		if (!this.ALPHANUMERIC_REGEX.test(text))
14929			throw "String contains unencodable characters in alphanumeric mode";
14930		var bb = new BitBuffer();
14931		var i;
14932		for (i = 0; i + 2 <= text.length; i += 2) {  // Process groups of 2
14933			var temp = QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;
14934			temp += QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));
14935			bb.appendBits(temp, 11);
14936		}
14937		if (i < text.length)  // 1 character remaining
14938			bb.appendBits(QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6);
14939		return new this(this.Mode.ALPHANUMERIC, text.length, bb);
14940	};
14941
14942
14943	/*
14944	 * Returns a new mutable list of zero or more segments to represent the given Unicode text string.
14945	 * The result may use various segment modes and switch modes to optimize the length of the bit stream.
14946	 */
14947	this.QrSegment.makeSegments = function(text) {
14948		// Select the most efficient segment encoding automatically
14949		if (text == "")
14950			return [];
14951		else if (this.NUMERIC_REGEX.test(text))
14952			return [this.makeNumeric(text)];
14953		else if (this.ALPHANUMERIC_REGEX.test(text))
14954			return [this.makeAlphanumeric(text)];
14955		else
14956			return [this.makeBytes(toUtf8ByteArray(text))];
14957	};
14958
14959
14960	/*
14961	 * Returns a segment representing an Extended Channel Interpretation
14962	 * (ECI) designator with the given assignment value.
14963	 */
14964	this.QrSegment.makeEci = function(assignVal) {
14965		var bb = new BitBuffer();
14966		if (0 <= assignVal && assignVal < (1 << 7))
14967			bb.appendBits(assignVal, 8);
14968		else if ((1 << 7) <= assignVal && assignVal < (1 << 14)) {
14969			bb.appendBits(2, 2);
14970			bb.appendBits(assignVal, 14);
14971		} else if ((1 << 14) <= assignVal && assignVal < 1000000) {
14972			bb.appendBits(6, 3);
14973			bb.appendBits(assignVal, 21);
14974		} else
14975			throw "ECI assignment value out of range";
14976		return new this(this.Mode.ECI, 0, bb);
14977	};
14978
14979
14980	// Package-private helper function.
14981	this.QrSegment.getTotalBits = function(segs, version) {
14982		if (version < MIN_VERSION || version > MAX_VERSION)
14983			throw "Version number out of range";
14984		var result = 0;
14985		for (var i = 0; i < segs.length; i++) {
14986			var seg = segs[i];
14987			var ccbits = seg.mode.numCharCountBits(version);
14988			// Fail if segment length value doesn't fit in the length field's bit-width
14989			if (seg.numChars >= (1 << ccbits))
14990				return null;
14991			result += 4 + ccbits + seg.getBits().length;
14992		}
14993		return result;
14994	};
14995
14996
14997	/*---- Constants for QrSegment ----*/
14998
14999	var QrSegment = {};  // Private object to assign properties to. Not the same object as 'this.QrSegment'.
15000
15001	// (Public) Can test whether a string is encodable in numeric mode (such as by using QrSegment.makeNumeric()).
15002	this.QrSegment.NUMERIC_REGEX = /^[0-9]*$/;
15003
15004	// (Public) Can test whether a string is encodable in alphanumeric mode (such as by using QrSegment.makeAlphanumeric()).
15005	this.QrSegment.ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+.\/:-]*$/;
15006
15007	// (Private) The set of all legal characters in alphanumeric mode, where each character value maps to the index in the string.
15008	QrSegment.ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
15009
15010
15011	/*---- Public helper enumeration ----*/
15012
15013	/*
15014	 * Represents the mode field of a segment. Immutable.
15015	 */
15016	this.QrSegment.Mode = {  // Constants
15017		NUMERIC     : new Mode(0x1, [10, 12, 14]),
15018		ALPHANUMERIC: new Mode(0x2, [ 9, 11, 13]),
15019		BYTE        : new Mode(0x4, [ 8, 16, 16]),
15020		KANJI       : new Mode(0x8, [ 8, 10, 12]),
15021		ECI         : new Mode(0x7, [ 0,  0,  0]),
15022	};
15023
15024
15025	// Private constructor.
15026	function Mode(mode, ccbits) {
15027		// (Package-private) An unsigned 4-bit integer value (range 0 to 15) representing the mode indicator bits for this mode object.
15028		Object.defineProperty(this, "modeBits", {value:mode});
15029
15030		// (Package-private) Returns the bit width of the segment character count field for this mode object at the given version number.
15031		this.numCharCountBits = function(ver) {
15032			if      ( 1 <= ver && ver <=  9)  return ccbits[0];
15033			else if (10 <= ver && ver <= 26)  return ccbits[1];
15034			else if (27 <= ver && ver <= 40)  return ccbits[2];
15035			else  throw "Version number out of range";
15036		};
15037	}
15038
15039
15040
15041	/*---- Private helper functions and classes ----*/
15042
15043	// Returns a new array of bytes representing the given string encoded in UTF-8.
15044	function toUtf8ByteArray(str) {
15045		str = encodeURI(str);
15046		var result = [];
15047		for (var i = 0; i < str.length; i++) {
15048			if (str.charAt(i) != "%")
15049				result.push(str.charCodeAt(i));
15050			else {
15051				result.push(parseInt(str.substr(i + 1, 2), 16));
15052				i += 2;
15053			}
15054		}
15055		return result;
15056	}
15057
15058
15059
15060	/*
15061	 * A private helper class that computes the Reed-Solomon error correction codewords for a sequence of
15062	 * data codewords at a given degree. Objects are immutable, and the state only depen
15062ds on the degree.
15063	 * This class exists because each data block in a QR Code shares the same the divisor polynomial.
15064	 * This constructor creates a Reed-Solomon ECC generator for the given degree. This could be implemented
15065	 * as a lookup table over all possible parameter values, instead of as an algorithm.
15066	 */
15067	function ReedSolomonGenerator(degree) {
15068		if (degree < 1 || degree > 255)
15069			throw "Degree out of range";
15070
15071		// Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which
15072		// is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}.
15073		var coefficients = [];
15074
15075		// Start with the monomial x^0
15076		for (var i = 0; i < degree - 1; i++)
15077			coefficients.push(0);
15078		coefficients.push(1);
15079
15080		// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
15081		// drop the highest term, and store the rest of the coefficients in order of descending powers.
15082		// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
15083		var root = 1;
15084		for (var i = 0; i < degree; i++) {
15085			// Multiply the current product by (x - r^i)
15086			for (var j = 0; j < coefficients.length; j++) {
15087				coefficients[j] = ReedSolomonGenerator.multiply(coefficients[j], root);
15088				if (j + 1 < coefficients.length)
15089					coefficients[j] ^= coefficients[j + 1];
15090			}
15091			root = ReedSolomonGenerator.multiply(root, 0x02);
15092		}
15093
15094		// Computes and returns the Reed-Solomon error correction codewords for the given
15095		// sequence of data codewords. The returned object is always a new byte array.
15096		// This method does not alter this object's state (because it is immutable).
15097		this.getRemainder = function(data) {
15098			// Compute the remainder by performing polynomial division
15099			var result = coefficients.map(function() { return 0; });
15100			data.forEach(function(b) {
15101				var factor = b ^ result.shift();
15102				result.push(0);
15103				for (var i = 0; i < result.length; i++)
15104					result[i] ^= ReedSolomonGenerator.multiply(coefficients[i], factor);
15105			});
15106			return result;
15107		};
15108	}
15109
15110	// This static function returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and
15111	// result are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.
15112	ReedSolomonGenerator.multiply = function(x, y) {
15113		if (x >>> 8 != 0 || y >>> 8 != 0)
15114			throw "Byte out of range";
15115		// Russian peasant multiplication
15116		var z = 0;
15117		for (var i = 7; i >= 0; i--) {
15118			z = (z << 1) ^ ((z >>> 7) * 0x11D);
15119			z ^= ((y >>> i) & 1) * x;
15120		}
15121		if (z >>> 8 != 0)
15122			throw "Assertion error";
15123		return z;
15124	};
15125
15126
15127
15128	/*
15129	 * A private helper class that represents an appendable sequence of bits.
15130	 * This constructor creates an empty bit buffer (length 0).
15131	 */
15132	function BitBuffer() {
15133
15134		// Packs this buffer's bits into bytes in big endian,
15135		// padding with '0' bit values, and returns the new array.
15136		this.getBytes = function() {
15137			var result = [];
15138			while (result.length * 8 < this.length)
15139				result.push(0);
15140			this.forEach(function(bit, i) {
15141				result[i >>> 3] |= bit << (7 - (i & 7));
15142			});
15143			return result;
15144		};
15145
15146		// Appends the given number of low bits of the given value
15147		// to this sequence. Requires 0 <= val < 2^len.
15148		this.appendBits = function(val, len) {
15149			if (len < 0 || len > 31 || val >>> len != 0)
15150				throw "Value out of range";
15151			for (var i = len - 1; i >= 0; i--)  // Append bit by bit
15152				this.push((val >>> i) & 1);
15153		};
15154	}
15155
15156	BitBuffer.prototype = Object.create(Array.prototype);
15157
15158};
15159;(function ( $, window, document, undefined ) {
15160    var isTouch = 'ontouchstart' in window,
15161        eStart = isTouch ? 'touchstart' : 'mousedown',
15162        eMove = isTouch ? 'touchmove' : 'mousemove',
15163        eEnd = isTouch ? 'touchend' : 'mouseup',
15164        eCancel = isTouch ? 'touchcancel' : 'mouseup';
15165
15166    function canPlayType( file ) {
15167        var audioElement = document.createElement( 'audio' );
15168        return !!( audioElement.canPlayType && audioElement.canPlayType( 'audio/' + file.split( '.' ).pop().toLowerCase() + ';' ).replace( /no/, '' ) );
15169    }
15170    function timeFormat( sec ) {
15171        function pad(num) {
15172            return ("0"+num).slice(-2);
15173        }
15174        var min = Math.floor(sec / 60);
15175        var hour = Math.floor(min / 60);
15176        sec = Math.floor(sec % 60);
15177        min = min % 60;
15178        return (hour > 0 ? hour + ":" : "") + pad(min) + ":" + pad(sec);
15179    }
15180    function playerSize( el ) {
15181        var playerEl = el,
15182            w = playerEl.outerWidth();
15183
15184        playerEl.removeClass('audioplayer-layout-480');
15185        playerEl.removeClass('audioplayer-layout-600');
15186        playerEl.removeClass('audioplayer-layout-900');
15187
15188        if (w >= 440) {
15189            playerEl.addClass('audioplayer-layout-480');
15190        }
15191        if (w >= 600) {
15192            playerEl.addClass('audioplayer-layout-600');
15193        }
15194        if (w >= 900) {
15195            playerEl.addClass('audioplayer-layout-900');
15196        }
15197    }
15198    function audioPlayerFullscreen( state, player ) {
15199        var playing = player.hasClass('audioplayer-playing');
15200        if ( state ) {
15201            if ( !$('.audioplayer__fullscreen').length ) {
15202                $('body').append('<div class="audioplayer__fullscreen m-hidden"></div>');
15203            }
15204            player.wrap('<div class="audioplayer__holder"></div>');
15205            $('.audioplayer__fullscreen').removeClass('m-hidden').append( player );
15206            ria.disablePageScroll(true);
15207            playerSize( player );
15208        } else {
15209            $('.audioplayer__holder').append( player );
15210            $('.audioplayer__fullscreen').addClass('m-hidden');
15211            player.unwrap();
15212            ria.disablePageScroll(false);
15213            playerSize( player );
15214        }
15215        if ( playing ) {
15216            player.find('audio').get(0).play();
15217        }
15218    }
15219    $.fn.audioPlayer = function( params ) {
15220        if ( !this.length || (this.length == 1 && $(this).hasClass('audioplayer-inited')) ) return;
15221        var locale = {};
15222        if (typeof player_locale !== "undefined") {
15223            locale = player_locale;
15224        }
15225        var params = $.extend( {
15226                classPrefix: 'audioplayer',
15227                strings: {
15228                    play: locale["Play"] ? locale["Play"] : 'Play',
15229                    pause: locale["Pause"] ? locale["Pause"] : 'Pause',
15230                    volume: locale["Mute"] ? locale["Mute"] : 'Mute',
15231                    volume2: locale["Unmute"] ? locale["Unmute"] : 'Unmute',
15232                    speed: locale["Playback Rate"] ? locale["Playback Rate"] : 'Playback Rate',
15233                    download: locale["Download"] ? locale["Download"] : 'Download',
15234                    subscribe: locale["Subscribe"] ? locale["Subscribe"] : 'Subscribe',
15235                    more: locale["More"] ? locale["More"] : 'More',
15236                    about: locale["About"] ? locale["About"] : 'About',
15237                }
15238            },
15239            params ),
15240            cssClass = {},
15241            cssClassSub = {
15242                playing: 'playing',
15243                stopped: 'stopped',
15244                noVolume: 'novolume',
15245                muted: 'muted',
15246                modal: 'modal'
15247            };
15248		var icons = {
15249			download: ria && ria.getIcon('download'),
15250			sound: ria && ria.getIcon('sound'),
15251			mute: ria && ria.getIcon('mute'),
15252			speed: ria && ria.getIcon('close'),
15253	        backward: ria && ria.getIcon('backward'),
15254			forward: ria && ria.getIcon('forward'),
15255			play: ria && ria.getIcon('play'),
15256			pause: ria && ria.getIcon('pause'),
15257			close: ria && ria.getIcon('close'),
15258			prev: ria && ria.getIcon('arrowLeft'),
15259			next: ria && ria.getIcon('arrowRight'),
15260			email: ria && ria.getIcon('email')
15261		}
15262
15263        for ( var subName in cssClassSub ) {
15264            cssClass[ subName ] = params.classPrefix + '-' + cssClassSub[ subName ];
15265        }
15266
15267        if (this.length > 1){
15268            this.each( function() {
15269                $(this).audioPlayer( params );
15270            });
15271            return this;
15272        }
15273
15274        var player = $(this),
15275            audio = player.find('audio').get(0);
15276
15277        playerSize( player );
15278        $(window).resize(function() {
15279            playerSize( player );
15280        });
15281
15282        var controls_subscribe = '';
15283        // console.log('pldata',player.data());
15284        if ( player.data('rubric') != '' ) {
15285            controls_subscribe = '<div class="audioplayer__subscribe audioplayer__top-button">'+
15286                    '<div class="audioplayer__subscribe-button">'+
15287                        '<span><svg class="svg-icon"><use xlink:href="' + icons['email'] + '" /></svg></span>'+
15288                        '<span>
15288' + params.strings.subscribe + '</span>'+
15289                    '</div>'+
15290                    '<div class="audioplayer__subscribe-list">'+
15291                        '<ul>'+
15292                            ( player.data('subscribe-itunes') != '' ? '<li><a class="audioplayer__subscribe-itunes" href="' + player.data('subscribe-itunes') + '" target="_blank">iTunes</a></li>' : '' ) +
15293                            ( player.data('subscribe-googlepodcasts') != '' ? '<li><a class="audioplayer__subscribe-googlepodcasts" href="' + player.data('subscribe-googlepodcasts') + '" target="_blank">Google</a></li>' : '' ) +
15294                            ( player.data('subscribe-spotify') != '' ? '<li><a class="audioplayer__subscribe-spotify" href="' + player.data('subscribe-spotify') + '" target="_blank">Spotify</a></li>' : '' ) +
15295                            ( player.data('subscribe-tunein') != '' ? '<li><a class="audioplayer__subscribe-tunein" href="' + player.data('subscribe-tunein') + '" target="_blank">TuneIn</a></li>' : '' ) +
15296                            ( player.data('subscribe-castbox') != '' ? '<li><a class="audioplayer__subscribe-castbox" href="' + player.data('subscribe-castbox') + '" target="_blank">Castbox</a></li>' : '' ) +
15297                            ( player.data('subscribe-soundstream') != '' ? '<li><a class="audioplayer__subscribe-soundstream" href="' + player.data('subscribe-soundstream') + '" target="_blank">Soundstream</a></li>' : '' ) +
15298                            ( player.data('subscribe-soundcloud') != '' ? '<li><a class="audioplayer__subscribe-soundcloud" href="' + player.data('subscribe-soundcloud') + '" target="_blank">SoundCloud</a></li>' : '' ) +
15299                            ( player.data('subscribe-yandexmusic') != '' ? '<li><a class="audioplayer__subscribe-yandexmusic" href="' + player.data('subscribe-yandexmusic') + '" target="_blank">Яндекс.Музыка</a></li>' : '' ) +
15300                            ( player.data('subscribe-rss') != '' ? '<li><a class="audioplayer__subscribe-rss" href="' + player.data('subscribe-rss') + '" target="_blank">RSS</a></li>' : '' ) +
15301                            // '<li><a href="https://ria.ru/export/itunes/rss2/' + player.data('rubric') + '.xml" target="_blank">RSS</a></li>'+
15302                            '<li class="hidden"><a href="/" class="audioplayer__ria-subscribe">Email</a></li>' +
15303                        '</ul>'+
15304                    '</div>'+
15305                '</div>';
15306        }
15307        var controls_right = '';
15308        var controls_download = '';
15309        var controls_playlist = '';
15310        var controls_about = '';
15311        if ( !player.hasClass('audioplayer-vast') ) {
15312            controls_right = '<div class="audioplayer__controls-right">'+
15313                    '<div class="audioplayer__controls-download" title="' + params.strings.download + '">'+
15314                        '<a href="' + audio.src + '" download="podcast" target="_blank"><svg class="svg-icon"><use xlink:href="' + icons['download'] + '" /></svg></a>'+
15315                    '</div>'+
15316                    '<div class="audioplayer__controls-share">'+
15317                        '<span class="share" data-id="' + player.data('articleid') +'" data-url="' + location.href + '" data-title="' + player.data('media-title').replace(/\\"/g, '&quot;') + '"></span>'+
15318                    '</div>'+
15319                '</div>';
15320            controls_download = '<div class="audioplayer__controls-download audioplayer__top-button" title="' + params.strings.download + '">'+
15321                    '<a href="' + audio.src + '" download="podcast" target="_blank">'+
15322                        '<span><svg class="svg-icon"><use xlink:href="' + icons['download'] + '" /></svg></span>'+
15323                        '<span>' + params.strings.download + '</span>'+
15324                    '</a>'+
15325                '</div>';
15326            controls_playlist = '<div class="audioplayer__modal audioplayer__playlist">'+
15327                    '<div class="audioplayer__modal-close"><svg class="svg-icon"><use xlink:href="'+ icons['close'] + '" /></svg></div>'+
15328                    '<div class="audioplayer__playlist-info">'+
15329                        '<div class="audioplayer__playlist-title">' + player.data('rubric-title').replace(/\\"/g, '"') + '</div>'+
15330                        '<div class="audioplayer__playlist-text">' + player.data('rubric-subtitle').replace(/\\"/g, '"') + '</div>'+
15331                        '<a href="' + player.data('rubric-url') + '" class="audioplayer__playlist-more">
15331' + params.strings.more + '</a>'+
15332                    '</div>'+
15333                    '<div class="audioplayer__playlist-list"><div class="audioplayer__playlist-list-content"></div></div>'+
15334                '</div>';
15335            controls_about = '<div class="audioplayer__modal audioplayer__about">'+
15336                    '<div class="audioplayer__modal-close"><svg class="svg-icon"><use xlink:href="'+ icons['close'] + '" /></svg></div>'+
15337                    '<div class="audioplayer__about-title">' + player.data('media-title').replace(/\\"/g, '"') + '</div>'+
15338                    '<div class="audioplayer__about-text"><div class="audioplayer__about-text-content">' + player.data('media-descr').replace(/\\"/g, '"') + '</div></div>'+
15339                '</div>';
15340        }
15341
15342        var controls1 = '<div class="audioplayer__controls hidden">'+
15343                        '<div class="audioplayer__current-time"></div>'+
15344                        '<div class="audioplayer__total-time"></div>'+
15345
15346                        '<div class="audioplayer__controls-seekbar">'+
15347                            '<div class="audioplayer__controls-seekbar-line">'+
15348                                '<div class="audioplayer__controls-seekbar-all"></div>'+
15349                                '<div class="audioplayer__controls-seekbar-loaded"></div>'+
15350                                '<div class="audioplayer__controls-seekbar-played"></div>'+
15351                            '</div>'+
15352                        '</div>'+
15353
15354                        '<div class="audioplayer__controls-left">'+
15355                            '<div class="audioplayer__controls-volume">'+
15356                                '<div class="audioplayer__controls-volume-button" title="' + params.strings.volume + '">'+
15357                                    '<svg class="svg-icon"><use xlink:href="'+ icons['sound'] +'" /></svg>'+
15358                                    '<svg class="svg-icon"><use xlink:href="'+ icons['mute'] +'" /></svg>'+
15359                                '</div>'+
15360                                '<div class="audioplayer__controls-volume-adjust"><div><div></div></div></div>'+
15361                            '</div>'+
15362                            '<div class="audioplayer__controls-speed">'+
15363                                '<div class="audioplayer__controls-speed-button" title="' + params.strings.speed + '">'+
15364                                    '<svg class="svg-icon"><use xlink:href="'+ icons['speed'] +'" /></svg><span>1</span>'+
15365                                '</div>'+
15366                                '<div class="audioplayer__controls-speed-list">'+
15367                                    '<ul>'+
15368                                        '<li data-value="0.8">0,8</li>'+
15369                                        '<li data-value="1" class="active">1</li>'+
15370                                        '<li data-value="1.5">1,5</li>'+
15371                                        '<li data-value="2">2</li>'+
15372                                    '</ul>'+
15373                                '</div>'+
15374                            '</div>'+
15375                        '</div>'+
15376                        '<div class="audioplayer__controls-center">'+
15377                            '<div class="audioplayer__controls-rw"><svg class="svg-icon"><use xlink:href="'+ icons['backward'] +'" /></svg></div>'+
15378                            '<div class="audioplayer__controls-play" title="' + params.strings.play + '">'+
15379                                '<svg class="svg-icon"><use xlink:href="'+ icons['play'] +'" /></svg>'+
15380                                '<svg class="svg-icon"><use xlink:href="'+ icons['pause'] +'" /></svg>'+
15381                            '</div>'+
15382                            '<div class="audioplayer__controls-fw"><svg class="svg-icon"><use xlink:href="'+ icons['forward'] +'" /></svg></div>'+
15383                        '</div>'+
15384
15385                        controls_right +
15386                    '</div>'+
15387
15388                    controls_subscribe +
15389
15390                    '<div class="audioplayer__prev hidden"><svg class="svg-icon"><use xlink:href="'+ icons['prev'] +'" /></svg></div>'+
15391                    '<div class="audioplayer__next hidden"><svg class="svg-icon"><use xlink:href="'+ icons['next'] +'" /></svg></div>'+
15392                    '<div class="audioplayer__about-button audioplayer__top-button"><span>i</span><span>
15392' + params.strings.about + '</span></div>'+
15393
15394                    controls_download +
15395                    controls_playlist +
15396                    controls_about;
15397
15398        player.append( controls1 );
15399
15400        var controls = player.find('.audioplayer__controls'),
15401            btnPlay = controls.find('.audioplayer__controls-play'),
15402            btnRW = controls.find('.audioplayer__controls-rw'),
15403            btnFW = controls.find('.audioplayer__controls-fw'),
15404            timeCurrent = controls.find('.audioplayer__current-time'),
15405            timeTotal = controls.find('.audioplayer__total-time'),
15406            seekbar = controls.find('.audioplayer__controls-seekbar'),
15407            seekbarPlayed = seekbar.find('.audioplayer__controls-seekbar-played'),
15408            seekbarLoaded = seekbar.find('.audioplayer__controls-seekbar-loaded'),
15409            volumeButton = controls.find( '.audioplayer__controls-volume-button' ),
15410            volumeAdjuster = controls.find( '.audioplayer__controls-volume-adjust > div' ),
15411            volumeDefault = 0,
15412            eventPushed = {p0: false, p25: false, p50: false, p75: false, p90: false},
15413            btnSpeed = controls.find('.audioplayer__controls-speed-button'),
15414            btnSpeedItem = controls.find('.audioplayer__controls-speed li'),
15415
15416            btnPrev = player.find('.audioplayer__prev'),
15417            btnNext = player.find('.audioplayer__next'),
15418            riaSubscribe =  player.find('.audioplayer__ria-subscribe'),
15419            adjustCurrentTime = function( e ) {
15420                realEvent = isTouch ? e.originalEvent.touches[ 0 ] : e;
15421                audio.currentTime = Math.round( ( audio.duration * ( realEvent.pageX - seekbar.offset().left ) ) / seekbar.width() );
15422            },
15423            adjustVolume = function( e ) {
15424                realEvent = isTouch ? e.originalEvent.touches[ 0 ] : e;
15425                var vol = Math.abs( ( realEvent.pageY - ( volumeAdjuster.offset().top + 85 ) ) / 85 );
15426                audio.volume = vol > 1 ? 1 : vol;
15427                ria.lsSet('audio_volume', audio.volume);
15428            },
15429            updateLoadBar = function() {
15430                var interval = setInterval( function() {
15431                    if ( audio.buffered.length < 1 ) {
15432                        return true;
15433                    }
15434                    seekbarLoaded.width( ( audio.buffered.end( 0 ) / audio.duration ) * 100 + '%' );
15435                    if ( Math.floor( audio.buffered.end( 0 ) ) >= Math.floor( audio.duration ) ) {
15436                        clearInterval( interval );
15437                    }
15438                }, 500 );
15439            };
15440
15441        var vast = {};
15442        vast.url = player.data('vast');
15443        var tracking_prefix = '';
15444
15445        var riaGetSubscribe = function( eml ){
15446            $.ajax({
15447                url: '/services/mailing/subscribe/?newsletter_id=' + player.data('subscribe-ria') + '&email=' + eml,
15448                dataType: 'json',
15449                beforeSend: function( xhr ) {
15450
15451                }
15452            }).done(function( data ){
15453                if( data.status == 'OK' ){
15454                    $('.js-subscribe').addClass('m-done');
15455                }
15456            });
15457        }
15458
15459        if ( riaSubscribe.length ) {
15460            riaSubscribe.on('click', function(){
15461                if ( GLOBAL.user.mail ) {
15462                    riaGetSubscribe( GLOBAL.user.mail ); // подписываем сразу
15463                } else {
15464                    modalLayer.open({
15465                            preset      : 'authorization',
15466                            beforeOpen  : function(){
15467                                //if ( !$('.modal__main-desc').length ) {
15468                                //    var $desc = $('<div />').addClass('modal__main-desc')
15469                                //                .text('Для подписки на рассылку вам необходимо авторизоваться или зарегистрироваться');
15470                                //    $('.modal__content.modal__auth').prepend( $desc );
15471                                //  console.log($('.modal__main-desc').length);
15472                                //}
15473                                GLOBAL.events.subscribe('login', function ( data ) {
15474                                    if ( data.status == 'success' ) {
15475                                        riaGetSubscribe( data.user.email );
15476                                    }
15477                                });
15478
15479                                if ( $('.modal__main-desc').length ) {
15480                                    // если поменял авторизацию на регистрацию
15481                                    $( window ).on('changeModalLayer', function(){
15482                                        $('.modal__main-desc').remove();
15483                                    })
15484                                }
15485                            },
15486                            afterClose : function(){
15487                                $('.modal__main-desc').remove();
15488                            //  console.log($('.modal__main-desc').length);
15489                            }
15490                        });
15491                }
15492                return false;
15493            })
15494        }
15495
15496        controls.removeClass('hidden');
15497
15498        var volumeTestDefault = audio.volume,
15499            volumeTestValue = audio.volume = 0;
15500        if ( Math.round( audio.volume * 1000 ) / 1000 == volumeTestValue ) {
15501            audio.volume = volumeTestDefault;
15502        } else {
15503            player.addClass( cssClass.noVolume );
15504        }
15505
15506        var cta_newsletter_id = player.attr('data-subscribe-ria');
15507
15508        if ( player.data('rubric') != '') {
15509            $.ajax({
15510                url: '/services/audio/' + player.data('rubric') + '/' + (cta_newsletter_id ? '?cta_newsletter_id=' + cta_newsletter_id : ''),
15511                dataType: "json"
15512            }).done(function( data ) {
15513                if ( data.items.length ) {
15514                    var html = '';
15515                    var pos = data.items.length;
15516                    player.find('.audioplayer__rubric span').html( data.items.length < 100 ? ' <span>' + pos + '</span>/' + pos : ' 99+' );
15517
15518                    $.each(data.items, function(i, item) {
15519                        var active = item.id == player.data('import-id') ? ' active' : '';
15520
15521                        if (active != '') {
15522                            player.find('.audioplayer__rubric span > span').text( pos );
15523                            player.find('.share').attr({
15524                                'data-url': item.url,
15525                                'data-id': item.articleid
15526                            });
15527                        }
15528                        var progress = '';
15529                        if ( ria.lsGet('audio_progress_' + item.id) ) {
15530                            progress = ' / <span>' + timeFormat( ria.lsGet('audio_progress_' + item.id) ) + '</span>';
15531                        }
15532                        html += '<div class="audioplayer__playlist-item' + active + '" data-src="' + item.mp3 + '" data-text="' + item.text.replace(/"/g, '&quot;') + '" data-cover="' + item.img + '" data-id="' + item.id + '" data-url="' + item.url + '" data-articleid="' + item.articleid + '"><div class="audioplayer__playlist-item-icon"><svg class="svg-icon"><use xlink:href="'+ icons['play'] +'" /></svg></div><div class="audioplayer__playlist-item-pos">' + (pos<10?'0'+pos:pos) + '</div><div class="audioplayer__playlist-item-main"><div class="audioplayer__playlist-item-title">' + item.title + '</div><div class="audioplayer__playlist-item-duration">' + timeFormat( item.duration ) + progress + '</div></div><div class="audioplayer__playlist-item-date">' + item.date + '</div></div>';
15533                        pos--;
15534                    });
15535                    player.find('.audioplayer__playlist-list-content').html( html );
15536                    player.find('.audioplayer__playlist-list').theinScroll();
15537                }
15538                if ( data.items.length > 1 ) {
15539                    btnPrev.removeClass('hidden');
15540                    btnNext.removeClass('hidden');
15541                } else {
15542                    btnPrev.addClass('hidden');
15543                    btnNext.addClass('hidden');
15544                }
15545                if ( typeof data.subscription_id !== 'undefined' && data.subscription_id != '' ) {
15546                    player.attr('data-subscribe-ria', data.subscription_id);
15547                    riaSubscribe.parent().removeClass('hidden');
15548                }
15549            }).fail(function(o, status) {
15550                // console.log('##',  status );
15551            });
15552        }
15553
15554        if ( typeof vast !== 'undefined' && typeof vast.url !== 'undefined') {
15555            tracking_prefix = 'banner_';
15556            $.ajax({
15557                url: vast.url
15558            }).done(function( data ) {
15559                var source = $(data).find('MediaFile').text().trim();
15560                audio.src = source;
15561                audio.addEventListener( 'loadedmetadata', function() {
15562                    player.removeClass('audioplayer-splash');
15563                });
15564                var tracking = $(data).find('TrackingEvents');
15565
15566                vast.tracking1 = tracking.find('Tracking[event="start"]').text().trim();
15567                vast.tracking2 = tracking.find('Tracking[event="firstQuartile"]').text().trim();
15568                vast.tracking3 = tracking.find('Tracking[event="midpoint"]').text().trim();
15569                vast.tracking4 = tracking.find('Tracking[event="thirdQuartile"]').text().trim();
15570                vast.tracking5 = tracking.find('Tracking[event="complete"]').text().trim();
15571                vast.tracking6 = tracking.find('Tracking[event="pause"]').text().trim();
15572            }).fail(function(o, status) {
15573
15574            });
15575        }
15576
15577        audio.volume = ria.lsGet('audio_volume') ? ria.lsGet('audio_volume') : 1;
15578        volumeAdjuster.find( 'div' ).height( audio.volume * 100 + '%' );
15579        volumeDefault = audio.volume;
15580        timeCurrent.text( timeFormat( 0 ) );
15581        timeTotal.text( $.isNumeric( audio.duration ) ? timeFormat( audio.duration ) : '' );
15582        audio.playbackRate = ria.lsGet('audio_playbackrate') ? ria.lsGet('audio_playbackrate') : 1;
15583        btnSpeed.find('span').text( audio.playbackRate );
15584        btnSpeedItem.removeClass('active').filter('[data-value="'+audio.playbackRate+'"]').addClass('active');
15585
15586        audio.addEventListener( 'loadedmetadata', function() {
15587            updateLoadBar();
15588            timeCurrent.text( timeFormat( 0 ) );
15589            timeTotal.text( $.isNumeric( audio.duration ) ? timeFormat( audio.duration ) : '...' );
15590        });
15591
15592        audio.addEventListener( 'playing', function() {
15593            $('.audioplayer').find('audio').each(function() {
15594                if ( $(this).get(0) != audio ) {
15595                    $(this).get(0).pause();
15596                }
15597            });
15598            player.addClass( cssClass.playing ).removeClass( cssClass.stopped );
15599            player.removeClass('audioplayer-splash');
15600            $('body').trigger( 'audioplayer', [ 'playing', player.attr('data-import-id') ] );
15601        });
15602        audio.addEventListener( 'pause', function() {
15603            player.removeClass( cssClass.playing ).addClass( cssClass.stopped );
15604            $('body').trigger( 'audioplayer', [ 'pause', player.attr('data-import-id') ] );
15605            if (typeof vast !== 'undefined' && typeof vast.tracking6 !== 'undefined') {
15606                fetch(vast.tracking6);
15607            }
15608        });
15609        window.dataLayer = window.dataLayer || [];
15610        audio.addEventListener( 'ended', function() {
15611            player.removeClass( cssClass.playing ).addClass( cssClass.stopped );
15612            $('body').trigger( 'audioplayer', ['ended', player.attr('data-import-id') ] );
15613            dataLayer.push({
15614                'event': tracking_prefix + 'Finished',
15615                'gaEventCategory': 'HTML5_Audio_Podcasts',
15616                'gaEventAction': 'Finished',
15617                'gaEventLabel': player.attr('data-media-title'),
15618                'player_rubric': player.attr('data-podcast')
15619            });
15620            if (typeof vast !== 'undefined' && typeof vast.tracking5 !== 'undefined') {
15621                fetch(vast.tracking5);
15622            }
15623        });
15624        audio.addEventListener( 'timeupdate', function() {
15625            var percent = ( audio.currentTime / audio.duration ) * 100;
15626            timeCurrent.text( timeFormat( this.currentTime ) );
15627            seekbarPlayed.width( percent + '%' );
15628            ria.lsSet('audio_progress_' + player.attr('data-import-id'), audio.currentTime);
15629
15630            if (audio.currentTime > 0 && audio.currentTime < 1 && !eventPushed.p0) {
15631                dataLayer.push({
15632                    'event': tracking_prefix + 'Play',
15633                    'gaEventCategory': 'HTML5_Audio_Podcasts',
15634                    'gaEventAction': 'Play',
15635                    'gaEventLabel': player.attr('data-media-title'),
15636                    'player_rubric': player.attr('data-podcast')
15637                });
15638                if (typeof vast !== 'undefined' && typeof vast.tracking1 !== 'undefined') {
15639                    fetch(vast.tracking1);
15640                }
15641                eventPushed.p0 = true;
15642            }
15643            if (percent >= 25 && !eventPushed.p25) {
15644                dataLayer.push({
15645                    'event': tracking_prefix + '25%',
15646                    'gaEventCategory': 'HTML5_Audio_Podcasts',
15647                    'gaEventAction': '25%',
15648                    'gaEventLabel': player.attr('data-media-title'),
15649                    'player_rubric': player.attr('data-podcast')
15650                });
15651                if (typeof vast !== 'undefined' && typeof vast.tracking2 !== 'undefined') {
15652                    fetch(vast.tracking2);
15653                }
15654                eventPushed.p25 = true;
15655            }
15656            if (percent >= 50 && !eventPushed.p50) {
15657                dataLayer.push({
15658                    'event': tracking_prefix + '50%',
15659                    'gaEventCategory': 'HTML5_Audio_Podcasts',
15660                    'gaEventAction': '50%',
15661                    'gaEventLabel': player.attr('data-media-title'),
15662                    'player_rubric': player.attr('data-podcast')
15663                });
15664                if (typeof vast !== 'undefined' && typeof vast.tracking3 !== 'undefined') {
15665                    fetch(vast.tracking3);
15666                }
15667                eventPushed.p50 = true;
15668            }
15669            if (percent >= 75 && !eventPushed.p75) {
15670                dataLayer.push({
15671                    'event': tracking_prefix + '75%',
15672                    'gaEventCategory': 'HTML5_Audio_Podcasts',
15673                    'gaEventAction': '75%',
15674                    'gaEventLabel': player.attr('data-media-title'),
15675                    'player_rubric': player.attr('data-podcast')
15676                });
15677                if (typeof vast !== 'undefined' && typeof vast.tracking4 !== 'undefined') {
15678                    fetch(vast.tracking4);
15679                }
15680                eventPushed.p75 = true;
15681            }
15682            if (percent >= 90 && !eventPushed.p90) {
15683                dataLayer.push({
15684                    'event': tracking_prefix + '90%',
15685                    'gaEventCategory': 'HTML5_Audio_Podcasts',
15686                    'gaEventAction': '90%',
15687                    'gaEventLabel': player.attr('data-media-title'),
15688                    'player_rubric': player.attr('data-podcast')
15689                });
15690                eventPushed.p90 = true;
15691            }
15692        });
15693        audio.addEventListener( 'volumechange', function() {
15694            volumeAdjuster.find( 'div' ).height( audio.volume * 100 + '%' );
15695            if ( audio.volume > 0 && player.hasClass( cssClass.muted ) ) {
15696                player.removeClass( cssClass.muted );
15697                audio.muted = false;
15698                volumeButton.attr('title', params.strings.volume);
15699            }
15700            if ( audio.volume <= 0 && !player.hasClass( cssClass.muted ) ) {
15701                player.addClass( cssClass.muted );
15702                audio.muted = true;
15703                volumeButton.attr('title', params.strings.volume2);
15704            }
15705        });
15706
15707        seekbar.on( eStart, function( e ) {
15708            adjustCurrentTime( e );
15709            seekbar.on( eMove, function( e ) {
15710                adjustCurrentTime( e );
15711            });
15712        }).on( eCancel, function() {
15713            seekbar.unbind( eMove );
15714        });
15715        // seekbar.on('click', function(e) {
15716        //     var rect = e.target.getBoundingClientRect();
15717        //     var pos = e.clientX - rect.left;
15718        //     audio.currentTime = duration * pos / player.width();
15719        // });
15720
15721        volumeButton.on( 'click', function() {
15722            if ( player.hasClass( cssClass.muted ) ) {
15723                player.removeClass( cssClass.muted );
15724                audio.muted = false;
15725                audio.volume = volumeDefault;
15726                $(this).attr('title', params.strings.volume);
15727            } else {
15728                player.addClass( cssClass.muted );
15729                audio.muted = true;
15730                volumeDefault = audio.volume;
15731                audio.volume = 0;
15732                $(this).attr('title', params.strings.volume2);
15733            }
15734        });
15735
15736        volumeAdjuster.on( eStart, function( e ) {
15737            adjustVolume( e );
15738            volumeAdjuster.on( eMove, function( e ) { adjustVolume( e ); } );
15739        }).on( eCancel, function() {
15740            volumeAdjuster.unbind( eMove );
15741        });
15742
15743        btnPlay.on( 'click', function() {
15744            if ( player.hasClass( cssClass.playing ) ) {
15745                $( this ).attr( 'title', params.strings.play );
15746                audio.pause();
15747            } else {
15748                $( this ).attr( 'title', params.strings.pause );
15749                audio.play();
15750            }
15751        });
15752
15753        btnRW.on( 'click', function() {
15754            audio.currentTime -= 30;
15755        });
15756        btnFW.on('click', function() {
15757            audio.currentTime += 30;
15758        });
15759
15760        btnSpeedItem.on('click', function() {
15761            audio.playbackRate = $(this).data('value');
15762            btnSpeed.find('span').text( $(this).text() );
15763            ria.lsSet('audio_playbackrate', audio.playbackRate);
15764            $(this).addClass('active').siblings().removeClass('active');
15765        });
15766
15767        player.find('.audioplayer__about-text').theinScroll();
15768
15769        function audioPlayerOpenModal( name ) {
15770            player.addClass( cssClass.modal ).attr('data-state', 'modal-' + name);
15771            player.find('.audioplayer__' + name).addClass('active');
15772
15773            // if ( !player.hasClass('audioplayer-layout-480') ) {
15774            if ( document.documentElement.clientWidth < 480 ) {
15775                audioPlayerFullscreen(true, player);
15776            }
15777        }
15778        function audioPlayerCloseModal( el ) {
15779            player.removeClass( cssClass.modal ).attr('data-state', '');
15780            el.removeClass('active');
15781
15782            if ( player.parent().hasClass('audioplayer__fullscreen') ) {
15783                audioPlayerFullscreen(false, player);
15784            }
15785        }
15786
15787        player.find('.audioplayer__rubric a').on('click', function(e) {
15788            if ( player.find('.audioplayer__playlist-item').length ) {
15789                e.preventDefault();
15790                audioPlayerOpenModal( 'playlist' );
15791            }
15792        });
15793        player.find('.audioplayer__about-button').on('click', function() {
15794            audioPlayerOpenModal( 'about' );
15795        });
15796        player.find('.audioplayer__modal-close').on('click', function() {
15797            audioPlayerCloseModal( $(this).parent() );
15798        });
15799
15800        player.find('.audioplayer__playlist-list').on('click', '.audioplayer__playlist-item', function() {
15801            var id = $(this).data('id');
15802            var mp3 = $(this).data('src');
15803            var cover = $(this).data('cover');
15804            var title = $(this).find('.audioplayer__playlist-item-title').text();
15805            var url = $(this).data('url');
15806            var articleid = $(this).data('articleid');
15807            var text = $(this).data('text');
15808            var pos = $(this).find('.audioplayer__playlist-item-pos').text();
15809            var playbackrate = audio.playbackRate;
15810
15811            $(this).addClass('active').siblings().removeClass('active');
15812
15813            audioPlayerCloseModal( $(this).closest('.audioplayer__modal') );
15814
15815            if (cover != '') {
15816                player.removeClass('audioplayer-nocover').find('.audioplayer__cover').css('background-image', 'url(' + cover + ')');
15817            } else {
15818                player.addClass('audioplayer-nocover').find('.audioplayer__cover').css('background-image', 'none');
15819            }
15820            player.attr('data-import-id', id);
15821            player.attr('data-media-title', title);
15822            player.find('.audioplayer__about-title').html( title );
15823            player.find('.audioplayer__rubric span > span').text( pos );
15824            player.find('.audioplayer__title').html( title );
15825            player.find('.audioplayer__about-text-content').html( text );
15826            player.find('.audioplayer__controls-download a').attr( 'href', mp3 );
15827            player.find('.share').attr({
15828                'data-url': url,
15829                'data-title': title,
15830                'data-id': articleid
15831            });
15832
15833            audio.src = mp3;
15834            eventPushed.p0 = false;
15835            eventPushed.p25 = false;
15836            eventPushed.p50 = false;
15837            eventPushed.p75 = false;
15838            eventPushed.p90 = false;
15839            audio.load();
15840            audio.playbackRate = playbackrate;
15841            audio.play();
15842        });
15843
15844        btnPrev.on('click', function() {
15845            if ( player.find('.audioplayer__playlist-item.active').next().length ) {
15846                player.find('.audioplayer__playlist-item.active').next().click();
15847            } else {
15848                player.find('.audioplayer__playlist-item:first').click();
15849            }
15850        });
15851        btnNext.on('click', function() {
15852            if ( player.find('.audioplayer__playlist-item.active').prev().length ) {
15853                player.find('.audioplayer__playlist-item.active').prev().click();
15854            } else {
15855                player.find('.audioplayer__playlist-item:last').click();
15856            }
15857        });
15858
15859        this.play = function() {
15860            audio.play();
15861        }
15862        this.pause = function() {
15863            audio.pause();
15864        }
15865        this.playitem = function( id ) {
15866            player.find('.audioplayer__playlist-item[data-id='+id+']').click();
15867        }
15868
15869        player.find('.audioplayer__title').on('click', function() {
15870            if ( player.hasClass('audioplayer-splash') ) {
15871                audio.play();
15872            }
15873        });
15874
15875        player.addClass('audioplayer-inited');
15876
15877        return this;
15878    };
15879})( jQuery, window, document );
15880
15881
15882$(function() {
15883    $('.audioplayer').audioPlayer();
15884    // riaShare.initItems( $('.audioplayer') );
15885});
15886
15887
15888function isAppleDevice() {
15889	return /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform);
15890}
15891
15892function ABSplitTest() {
15893	var cookie = $("#body").data('ab'),
15894		cookieName = 'ab_emoji_test';
15895
15896	if(typeof ria === 'object' && cookie !== ''){
15897		ria.setCookie(cookieName, cookie, 60 * 1000 * 60 * 24 * 30, '/');
15898	}
15899}
15900
15901
15902function ABFloorDate() {
15903	if(typeof ria === 'object'){
15904		var cookieName = 'ab_mainpage';
15905		var cookie = ria.getCookie(cookieName);
15906		var urlParam = ria.getUrlParameter('abtest');
15907
15908		if(urlParam){
15909			cookie = urlParam;
15910			ria.setCookie(cookieName, cookie, 60 * 1000 * 60 * 24 * 30, '/');
15911		} else if(!cookie){
15912			cookie = Math.random() > .5 ? 'a' : 'b';
15913			ria.setCookie(cookieName, cookie, 60 * 1000 * 60 * 24 * 30, '/');
15914		}
15915
15916		if(cookie === 'a'){
15917			$('.cell__controls-date').removeClass('m-hidden');
15918		}
15919	}
15920}
15921
15922
15923$(function(){
15924	ABSplitTest();
15925	// ABFloorDate();
15926
15927	if (typeof ria === 'object' && (window.location.host.indexOf('devel') >= 0 || window.location.host.indexOf('beta') >= 0 || window.location.search.indexOf('iubenda_disable') >= 0)) {
15928		ria.setCookie('iubenda_disabled', '1', 60 * 1000 * 60 * 24 * 30 * 60, '/');
15929	}
15930	if (typeof ria === 'object' && window.location.search.indexOf('iubenda_show') >= 0) {
15931		ria.setCookie('iubenda_show', '1', 60 * 1000 * 60 * 24 * 30 * 60, '/');
15932	}
15933
15934	if (isAppleDevice()) {
15935		$('#body').addClass('m-apple');
15936	}
15937
15938	let header = $('#anchor').offset().top;
15939	$(window).on('scroll',function(){
15940		let top = $( window ).scrollTop()
15941
15942		if(top > header){
15943			$('#body').addClass('m-header-sticked');
15944		} else {
15945			$('#body').removeClass('m-header-sticked');
15946		}
15947	});
15948
15949	GLOBAL.projectWidgetInit = false;
15950	$('body').on('widget', function(e, n, s) {
15951		if (n === 'project' && s && !GLOBAL.projectWidgetInit && GLOBAL.projectList) {
15952			var project = _.template($('#project').html());
15953			$('#projectWrapper').append( project({data: GLOBAL.projectList}).trim()).each(function() {
15954				$(this).find('.project__place-scroll').theinScroll({
15955					rtl: Boolean(GLOBAL.rtl)
15956				});
15957			});
15958			GLOBAL.projectWidgetInit = true;
15959		}
15960	});
15961
15962	$(".switcher").on('click', '.switcher__label', function(e) {
15963		e.preventDefault();
15964		e.stopPropagation();
15965		let switcher = $(this).closest(".switcher");
15966		let body = $('body');
15967
15968		if(switcher.hasClass('m-active') ){
15969			switcher.removeClass('m-active');
15970			body.removeClass('m-switcher');
15971			switcher.find('.switcher__dropdown').fadeOut(200);
15972			$(document).off('click.switcher-click');
15973		}else{
15974			switcher.addClass('m-active');
15975			body.addClass('m-switcher');
15976			switcher.find('.switcher__dropdown').fadeIn(200);
15977			$(document).one('click.switcher-click', function() {
15978				switcher.removeClass('m-active');
15979				switcher.find('.switcher__dropdown').fadeOut(200);
15980			});
15981		}
15982	}).on('click', ".switcher__list", function(e) {
15983		e.stopPropagation();
15984	});
15985
15986	if (typeof ria === 'object' && (parseInt(ria.getCookie('privacy_policy')) !== 1 || ria.getCookie('privacy_policy') === undefined || ria.getUrlParameter('privacy_policy'))){
15987		let gdpr = $('#gdpr');
15988		let button = $('#gdpr .gdpr__btn');
15989
15990		if(gdpr.length) {
15991			gdpr.addClass('m-active');
15992			if(ria.getClientHeigth() < ($('#gdpr').height() + $('#header').height())){
15993				ria.disablePageScroll(true);
15994			}
15995
15996			button.click(function(e){
15997				e.preventDefault();
15998				ria.setCookie('privacy_policy', '1', 60 * 1000 * 60 * 24 * 730, '/');
15999				ria.disablePageScroll();
16000				gdpr.removeClass('m-active');
16001			})
16002		}
16003	}
16004
16005	$(".footer__menu").theinCarousel({
16006		nav: false,
16007		itemAutoWidth: true,
16008		sticked: false,
16009		lessCenter: false,
16010		outside: 0,
16011		between: 20,
16012		rtl: Boolean(GLOBAL && GLOBAL.rtl),
16013		motionType : 'scroll'
16014	});
16015
16016
16017	$('#radioButton').on('click', function(){
16018		// let th = $(this);
16019		// let au = th.find('audio');
16020
16021		// if(!au.length){
16022		// 	th.append('<audio src="' + th.data('stream') + '" />');
16023		// 	au = th.find('audio');
16024		// }
16025
16026		// let audio = au.get(0);
16027		// if(audio.paused){
16028		// 	th.addClass('m-active');
16029		// 	audio.play();
16030		// } else{
16031		// 	th.removeClass('m-active');
16032		// 	audio.pause();
16033		// }
16034		var openPopup = function(url, params) {
16035			var left = Math.round(screen.width/2 - params.width/2);
16036			var top = 0;
16037			if (screen.height > params.height) {
16038				top = Math.round(screen.height/3 - params.height/2);
16039			}
16040			var win = window.open(url, 'sl_' + this.service, 'left=' + left + ',top=' + top + ',' + 'width=' + params.width + ',height=' + params.height + ',personalbar=0,toolbar=0,scrollbars=1,resizable=1');
16041			if (win) {
16042				win.focus();
16043			} else {
16044				location.href = url;
16045			}
16046		}
16047		openPopup('/broadcasts/live/', {
16048			width: 820,
16049			height: 570
16050		});
16051	});
16052
16053	if($('.footer__social-button').length) {
16054		$(".footer__social").theinCarousel({
16055			nav: false,
16056			itemAutoWidth: true,
16057			outside: 0,
16058			between: 20,
16059			motionType: 'scroll',
16060			lessCenter: false,
16061			rtl: Boolean(GLOBAL && GLOBAL.rtl),
16062			responsive: {
16063				480: {
16064					outside: 0
16065				},
16066				1235: {
16067					outside: 0
16068				}
16069			}
16070		});
16071
16072		$('.footer__social-button[title=WeChat]').on('click',function (e) {
16073			e.preventDefault()
16074			e.stopPropagation()
16075			const offset = $(this).offset()
16076			const popup = $(this).find('.footer__social-popup')
16077			popup.css({'display': 'flex', top:offset.top - $(window).scrollTop() - popup.outerHeight() - 10, left:offset.left + $(this).outerWidth() / 1})
16078
16079			function socialDestroy() {
16080				$(document).off('click.social-button');
16081				$(document).off('scroll.social-button');
16082				$(window).off('resize.social-button');
16083				popup.css({display:none});
16084			}
16085
16086			$(document).on('resize.social-button click.social-button scroll.social-button', function (e) {
16087				$(document).off('click.social-button');
16088				$(document).off('scroll.social-button');
16089				$(document).off('resize.social-button');
16090				popup.css({'display': 'none'});
16091			});
16092		})
16093	}
16094
16095	if(typeof riaCells === "function"){
16096		riaCells();
16097	}
16098
16099	if(typeof riaShare === "object"){
16100		riaShare.init();
16101	}
16102
16103	if(typeof photoViewWidget ===  'object') {
16104		photoViewWidget.init();
16105	}
16106
16107	$( '.js-vote' ).riaVote();
16108
16109	if(typeof lazyload === 'function') {
16110		lazyload();
16111		$('body').on('nextarticle', function(e) {
16112			lazyload();
16113		});
16114	}
16115
16116	if(typeof ria === 'object') {
16117		ria.convertDate();
16118	}
16119
16120	$('.js__custom-scroll').theinScroll({
16121		rtl:Boolean(GLOBAL.rtl)
16122	});
16123
16124	$( '.victorina' ).riaVictorina();
16125
16126	// Открыть чат и сообщение по ссылке
16127	if (typeof ria === 'object' && ria.getUrlParameter('chat_room_id') && ria_chat_manager) {
16128		if (ria.getUrlParameter('chat_message_id')) {
16129			ria_chat.state.goto_message = ria.getUrlParameter('chat_message_id');
16130		}
16131		ria_chat_manager.openArticleRoom(ria.getUrlParameter('chat_room_id'));
16132	}
16133
16134	var matchcenter = $('.tournament-floor__table:visible').length ?  $('.tournament-floor__table:visible') : $('ul.matchcenterlive__list:visible')
16135	if (matchcenter.length) {
16136		matchcenter.theinCarousel({
16137			nav: true,
16138			navText : [`<i><svg class="svg-icon"><use xlink:href="${ria.getIcon('arrowLeft')}"/></svg></i>`,`<i><svg class="svg-icon"><use xlink:href="${ria.getIcon('arrowRight')}"/></svg></i>`],
16139			itemAutoWidth: !Boolean($('.tournament-floor__table:visible').length),
16140			between: 0,
16141			stretch: false,
16142			outside: 0,
16143			rtl: Boolean(GLOBAL && GLOBAL.rtl),
16144		});
16145
16146		setTimeout(() => {
16147			var count_finished = matchcenter.find('.matchcenter__match[status="finished"]').length;
16148			if (count_finished) {
16149				matchcenter.trigger('change.the-in-carousel', count_finished);
16150			}
16151		}, 1000);
16152
16153		$('.the-in-carousel__nav-button', matchcenter).on('click', function (btn) {
16154			dataLayer && dataLayer.push({
16155				'event': 'olympiad_widget',
16156				'eventCategory': 'Widget',
16157				'eventAction': 'Click',
16158				'eventLabel': btn.currentTarget.classList.contains('the-in-carousel__nav-prev') ? 'Left' : 'Right'
16159			});
16160		})
16161
16162		$('.the-in-carousel__pack', matchcenter).on('click', function () {
16163			dataLayer && dataLayer.push({
16164				'event': 'olympiad_widget',
16165				'eventCategory': 'Widget',
16166				'eventAction': 'Click',
16167				'eventLabel': 'Other'
16168			});
16169		})
16170
16171		$('.tournament-floor__info').on('click', function () {
16172			dataLayer && dataLayer.push({
16173				'event': 'olympiad_widget',
16174				'eventCategory': 'Widget',
16175				'eventAction': 'Click',
16176				'eventLabel': 'Other'
16177			});
16178		})
16179
16180		$('.matchcenterlive__link').on('click', function () {
16181			console.log('click');
16182			dataLayer && dataLayer.push({
16183				'event': 'olympiad_widget',
16184				'eventCategory': 'Widget',
16185				'eventAction': 'Click',
16186				'eventLabel': 'Matchcentrerlive'
16187			});
16188		})
16189	}
16190
16191
16192	$('.matchcenter__tabs-item').on('click', function(e) {
16193		e.preventDefault();
16194
16195		$(this).addClass('m-active').siblings('.matchcenter__tabs-item').removeClass('m-active');
16196		$(this.hash).addClass('m-active').siblings('.matchcenter__content').removeClass('m-active');
16197	})
16198
16199	$('.matchcenter__groups-tabs-item').on('click', function(e) {
16200		e.preventDefault();
16201
16202		$(this).addClass('m-active').siblings('.matchcenter__groups-tabs-item').removeClass('m-active');
16203		$(this.hash).addClass('m-active').siblings('.matchcenter__groups-content').removeClass('m-active');
16204	})
16205
16206	var data = {}
16207	if($('#modals').data('sid') !== '') {
16208		data.sid = $('#modals').data('sid')
16209	}
16210
16211	if (ria.getUrlParameter('secret') !== '') {
16212		data.secret = ria.getUrlParameter('secret')
16213	}
16214
16215	if (ria.getUrlParameter('template')) {
16216		data.template = '1'
16217	}
16218	$.ajax({
16219		url: '/services/popups.html',
16220		dataType: 'html',
16221		data: data,
16222		type: 'GET',
16223		success: function ( data ) {
16224			const $modal = $(data);
16225
16226			loadCSS( $modal.data('css') );
16227			loadJS( $modal.data('js') );
16228
16229			$('#modals').append($modal);
16230		}
16231	});
16232
16233	$('a[data-modal-open]').on('click', function(e) {
16234		let linkAuth = e.target.closest('a');
16235
16236		if (linkAuth && linkAuth.hasAttribute('auth')) {
16237			e.preventDefault();
16238		}
16239	});
16240	if (document.querySelectorAll('input[name="tabset"]')[1] && document.querySelector('.audioplayer audio')) {
16241		document.querySelectorAll('input[name="tabset"]')[1].addEventListener('change', function() {
16242			document.querySelector('.audioplayer audio').pause();
16243		});
16244	}
16245});
16246
16247function getDatepickerLocale() {
16248	var result = 'en';
16249
16250	if (GLOBAL && GLOBAL.lang === 'rus') {
16251		result = 'ru';
16252	} else if (GLOBAL && GLOBAL.lang === 'eng') {
16253		result = 'en';
16254	} else if (GLOBAL && GLOBAL.design) {
16255		result = GLOBAL.design;
16256	}
16257
16258	return result;
16259}
16260$(function() {
16261	$.fn.subscr = function() {
16262
16263		return this.each(function() {
16264
16265			var $this      = $(this),
16266				$submail   = $this.find('[data-type = "input"] input[name="email"]'),
16267				$form      = $this.find('[data-type = "form"]'),
16268				$submit    = $this.find('[data-type="submit"] input[type="submit"]'),
16269				$desc      = $this.find('[data-type = "desc"]'),
16270				$tz        = $this.find('.tz');
16271
16272			var now = new Date();
16273			$tz.val( now.getTimezoneOffset() );
16274
16275			if (typeof Intl.DateTimeFormat == 'function') {
16276				$tz.val( Intl.DateTimeFormat().resolvedOptions().timeZone );
16277			}
16278
16279			if ( GLOBAL.user.mail && GLOBAL.user.emailActive === 'OK') {
16280				$this.addClass('m-email');
16281				$form.removeClass('m-invalid');
16282				$submail.attr({ 'value' : GLOBAL.user.mail});
16283			}
16284
16285			$submit.on('click', function(e){
16286				e.preventDefault();
16287
16288				if ( !($form.hasClass('m-invalid')) ) {
16289					$.ajax({
16290						url  : $form.data('ajax'),
16291						data : {
16292							'email'         : $submail.val(),
16293							'tz'            : $tz.val(),
16294							'title'         : $form.data('title'),
16295							'newsletter_id' : $form.data('newsletter')
16296						},
16297						dataType: 'json',
16298						beforeSend: function( xhr ) {
16299							// $desc.text('');
16300
16301						}
16302					}).done(function( data ){
16303						if( data.status === 'OK' ) {
16304							$desc.text('');
16305							$this.addClass('m-done');
16306							$desc.text(data.message);
16307						}
16308					});
16309				}
16310			});
16311
16312			//var socialNetworkStack;
16313
16314		});
16315	};
16316	$('.js-subscribe').subscr()
16317});
16318"use strict";
16319
16320$(function() {
16321	function clampRecomendation($obj) {
16322		$(".recommendation__announce").each(function() {
16323			var $title = $(this).find('.recommendation__clamp');
16324			if($(this) && $title && $title.height() > $(this).height()){
16325				if($title.text().indexOf(' ') > 0 && $(this).height() > 30) {
16326					while ($title.height() > $(this).height()) {
16327						$title.text($title.text().split(" ").slice(0, $title.text().split(" ").length - 1).join(" ") + "...");
16328					}
16329				}
16330				else {
16331					$(this).remove();
16332				}
16333			}
16334		});
16335	}
16336
16337	window.startArticleJS = function( obj, type ){
16338		obj.each(function(){
16339			var $obj = $( this );
16340			// Подгрузка динамики
16341			if(GLOBAL && GLOBAL.htmlCache){
16342				$obj.addingDinamicData();
16343			}
16344			// $obj.addingDinamicData();
16345			// Инициализация скриптов в статье
16346			initArticleJS( obj, type );
16347		});
16348	};
16349
16350
16351	window.initArticleJS = function( obj, type ){
16352		obj.each( function(){
16353
16354			var $obj = $( this );
16355
16356			// кнопки шары в статье
16357			var $share = $obj.find('.article__sharebar');
16358			if ( $share.length > 0 ) {
16359				var defaultHeaderIndent = 40,                                               // расстояние от шапки на ria
16360					lentaHeaderIndent = $('body').hasClass('m-lenta-alert') ? 46 : 0;       // добавок расстояния от шапки для сайта с лентой
16361				if ( type != 'first' ) riaShare.initItems( $share );
16362				if ( $share.hasClass('m-article-sticky') && typeof ria === 'object' && !ria.supportsCSS( 'position', 'sticky' ) ) {
16363					$share.riaShareSliding({
16364						frame: '.article__sharebar-line',
16365						header: '#headerSticked',
16366						headerIndent: ( defaultHeaderIndent + lentaHeaderIndent )
16367					});
16368				}
16369			}
16370
16371			//
16372			var $ctaBlock = $obj.find('#cta');
16373			if ( $ctaBlock.length && typeof ctaRotate !== "undefined") {
16374				$ctaBlock.cta(ctaRotate);
16375			}
16376			if ( $obj.find('.cta2').length && typeof ctaRotate2 !== "undefined" ) {
16377				$obj.find('.cta2').cta(ctaRotate2);
16378			}
16379
16380			var $mc_share = $obj.find('.matchcenterlive__article-sharebar');
16381			if ( $mc_share.length > 0 && typeof ria === 'object' && !ria.supportsCSS( 'position', 'sticky' ) ){
16382				$mc_share.riaShareSliding({
16383					frame : '.matchcenterlive__article-sharebar-line',
16384					header : '#headerSticked',
16385					headerIndent : ( defaultHeaderIndent + lentaHeaderIndent )
16386				});
16387			}
16388
16389			// слайдинг правой колонки
16390			if (typeof ria === 'object' && !( ria.supportsCSS( 'position', 'sticky' ) && ria.supportsCSS( 'display', 'flex' ) ) ) {
16391				$obj.find('.js-slide-block').riaSliding({
16392					frame: '.layout-article__over',
16393					anchor: '.layout-article__right-column-anchor',
16394					topIndent: '#headerSticked',
16395					addedIndent : 10
16396				});
16397			}
16398
16399			// // кнопка скрытия видео баннера 1053 позиция
16400			$obj.find('.banner__hidden-button').click( function(){
16401				$( this ).parents( '.article__block:first' ).empty().addClass('m-hidden');
16402			});
16403
16404			// раскрытие врезов
16405			$obj.find('.article__incision').each( function() {
16406				var $el = $(this);
16407
16408				$('.article__incision-button', $el).on( 'click', function(e) {
16409					e.preventDefault();
16410					$(this).parent().toggleClass('m-extended');
16411				});
16412			});
16413
16414
16415			$obj.find(".article__author" ).theinCarousel({
16416				navText : [`<svg class="svg-icon"><use xlink:href="${ria.getIcon('arrowLeft')}"/></svg>`,`<svg class="svg-icon"><use xlink:href="${ria.getIcon('arrowRight')}"/></svg>`],
16417				nav:false,
16418				motionType : 'transform',
16419				loop: false,
16420				itemWidth:300,
16421				rtl: Boolean(GLOBAL && GLOBAL.rtl),
16422				responsive:{
16423					1190:{
16424						nav: Boolean($obj.find(".article__author .article__author-item").length > 2)
16425					}
16426				}
16427			});
16428
16429			// PHOTO CAROUSEL
16430			$obj.find(".article__photo.m-carousel .article__photo-item-set" ).each( function() {
16431				var $carousel = $( this ),
16432					$photo = $carousel.parents( '.article__photo.m-carousel:first' );
16433				// смена описания во внешнем блоке
16434				var $outer =  $('.article__photo-outer-desc', $photo ),
16435					$outerDescs = $('.article__photo-item-desc', $outer);
16436				$outerDescs.css('position', 'initial');
16437				$carousel.on( 'changed.the-in-carousel', function( event, data ){
16438					if ( $outer.is(':visible') ){
16439						var active = data.plugin._current.active;
16440						$outerDescs
16441							.hide()
16442							.find('.article__photo-item-over')
16443							.stop()
16444							.css('opacity', 0);
16445						$('.article__photo-item-desc[data-item='+active+']', $outer)
16446							.show()
16447							.find('.article__photo-item-over')
16448							.animate( {
16449								opacity : 1
16450							}, 250 );
16451					}
16452				});
16453				var responsive = {
16454					0: {
16455						itemWidth: '90%',
16456						between: 5
16457					}
16458				};
16459				// if ( type != 'online' ){
16460				responsive['925'] = {
16461					sticked: true,
16462					items: 1,
16463					between: 0
16464				}
16465				// }
16466				// запуск карусели
16467				$carousel.theinCarousel({
16468					navText : [`<svg class="svg-icon"><use xlink:href="${ria.getIcon('arrowLeft')}"/></svg>`,`<svg class="svg-icon"><use xlink:href="${ria.getIcon('arrowRight')}"/></svg>`],
16469					motionType : 'transform',
16470					loop: true,
16471					rtl: Boolean(GLOBAL && GLOBAL.rtl),
16472					responsive: responsive
16473				});
16474				// образмеривание описаний
16475				var dimension = function( wrapper ){
16476					var $wrapper = $( '.' + wrapper, $photo );
16477					if ( $wrapper.is(':visible') ){
16478						var $items = $( '.article__photo-item-desc', $wrapper);
16479						var h = 0;
16480						$items.each(function(){
16481							var ch = $(this).outerHeight( true );
16482							if ( ch > h ) h = ch;
16483						});
16484						$wrapper.height( h );
16485					}
16486				};
16487				$( window ).resize( function(){
16488					dimension( 'article__photo-outer-desc' );
16489					dimension( 'article__photo-inner-desc' );
16490				});
16491				$( window ).resize();
16492			});
16493
16494			//
16495			// // video / audio / vote / victorina / instagram
16496			if ( type != 'first' ) {
16497				$('body').trigger('nextarticle');
16498
16499				document.dispatchEvent(
16500					new CustomEvent('nextarticle', {
16501						bubbles: true,
16502						detail: { articleid: $obj.data('id')}
16503					})
16504				);
16505
16506				if ( $( this ).find('.video-js').length && !window.videojs ) {
16507					loadJS( GLOBAL.js.videoplayer );
16508				} else {
16509					$( this ).find('.video-js').each(function() {
16510						videoInit( $(this) );
16511					});
16512				}
16513
16514				$( this ).find('.audioplayer').audioPlayer();
16515
16516				// $( this ).find( '.js-vote' ).riaVote();
16517
16518				$( this ).find( '.victorina' ).riaVictorina();
16519
16520				if( window.instgrm && window.instgrm.Embeds ){
16521					window.instgrm.Embeds.process();
16522				}
16523				if (window.twttr && window.twttr.widgets) {
16524					twttr.widgets.load();
16525				}
16526
16527				if ( !window.partnersjs && typeof partners !== "undefined" && ($(this).find('.js-test-partner-1').length || $(this).find('.js-test-partner-2').length) ) {
16528					loadJS( GLOBAL.js.partners );
16529				}
16530
16531			}
16532
16533			if(typeof ria === 'object'){
16534				ria.convertDate();
16535				clampRecomendation();
16536			}
16537		});
16538	};
16539
16540
16541	var addingDinamicData = function( element, options ){
16542
16543		var	defaults = {
16544			loadingCounter : 0,
16545			loadingCount : 3,
16546			loadingTimeout : 2000,
16547			loadingDate : false,
16548			loadingId : false
16549		};
16550
16551		this.defOptions = defaults;
16552		this.userOptions = options;
16553		this.options = $.extend( true, {}, defaults, options );
16554
16555		/** Dinamic data element */
16556		this.$element = $( element );
16557		this.loadingDate = this.options.loadingDate || this.$element.data( 'date' );
16558		this.loadingId = this.options.loadingId || this.$element.data( 'id' );
16559
16560		if ( this.loadingDate && this.loadingId ) {
16561			this.$data = false;
16562			var preview = '';
16563			var endless = '';
16564			if (window.location.pathname.indexOf('editorial_preview') != -1) {
16565				preview = (window.location.search != '' ? '&' : '?') + 'preview=1';
16566			}
16567			endless = ((window.location.search != '' || preview != '') ? '&' : '?') + 'endless=' + this.$element.data( 'endless' );
16568			this.loadingUrl = '/services/dynamics/' + this.$element.data( 'date' ) + '/' + this.$element.data( 'id' ) + '.html'+ ( window.location.search != '' ? window.location.search : '' ) + preview + endless;
16569			this.getData();
16570		} else {
16571			console.log( ' addingDinamicData not possible to start' );
16572		}
16573
16574	};
16575
16576	addingDinamicData.prototype.getData = function(){
16577		var _this = this;
16578		$.ajax({
16579			url: _this.loadingUrl,
16580			dataType: 'html',
16581			type: 'GET',
16582			success: function ( data ) {
16583				_this.$data = $( data );
16584				_this.successData();
16585			},
16586			error: function (){
16587				if ( _this.options.loadingCounter < _this.options.loadingCount ){
16588					setTimeout( _this.getData() , _this.options.loadingTimeout );
16589					_this.options.loadingCounter++;
16590				} else {
16591					_this.errorData();
16592				}
16593			}
16594		});
16595	};
16596
16597	addingDinamicData.prototype.pushRecommend = function(){
16598		var _this = this,
16599			$recommend = $( '.recommendation', _this.$data ),
16600			$recommendPlace = $( '.recommendation__place', _this.$element );
16601
16602		if ( $recommend.length > 0 && $recommendPlace.length > 0 ){
16603			$recommendPlace.empty().append( $recommend );
16604			if ( typeof lazyload == 'function' ) lazyload();
16605			ria.convertDate();
16606			riaShare.initItems($recommend);
16607			clampRecomendation();
16608		} else {
16609			$recommendPlace.remove();
16610		}
16611	};
16612
16613	addingDinamicData.prototype.successData = function(){
16614		var _this = this;
16615		//console.log( '--- SUCCESS GetData --- ' + _this.loadingUrl );
16616		_this.pushRecommend();
16617		_this.pushBestComments();
16618		_this.pushUserBar();
16619		_this.pushChatButtonToShare();
16620		_this.pushArticleBlocksViews();
16621		_this.pushStatistic();
16622	};
16623
16624	addingDinamicData.prototype.errorData = function(){
16625		var _this = this;
16626		console.log( '--- ERROR GetData --- ' + _this.loadingUrl );
16627	};
16628
16629	addingDinamicData.prototype.pushBestComments = function(){
16630		var _this = this,
16631			$bestComments = $( '.best-comments', _this.$data ),
16632			$bestCommentsPlace = $( '.article__best-comments', _this.$element );
16633
16634		if ( $bestComments.length > 0 && $bestCommentsPlace.length > 0 ){
16635			$bestCommentsPlace
16636				// .on( 'click', '.best-comments__item-message-text', function(){ $( this ).removeClass('m-collapsed') })
16637				.replaceWith( $bestComments )
16638				// .slideDown();
16639		}else{
16640			$bestCommentsPlace.remove()
16641		}
16642	};
16643
16644	addingDinamicData.prototype.pushStatistic = function(){
16645		var _this = this,
16646			$statisticPlace = $( '.article__view', _this.$element ),
16647			$id = $( '.article__view', _this.$element ).data('id'),
16648			$statistic = $( '.views[data-id='+$id+']', _this.$data );
16649
16650		if ( $statistic.length > 0 && $statisticPlace.length > 0 ){
16651			$statisticPlace.empty().append( $statistic );
16652		} else {
16653			$statisticPlace.remove();
16654		}
16655	};
16656
16657	addingDinamicData.prototype.pushArticleBlocksViews = function(){
16658		var _this = this,
16659			$views = $('.articleblocks__views',_this.$data),
16660			$articleblock = $('.elem-info__views', _this.$element);
16661
16662			$articleblock.each(function () {
16663				var el = $(this),
16664					id = el.data('id'),
16665					view = $views.find('[data-id='+id+']');
16666
16667				if(view.length){
16668					el.empty().append(view);
16669				}else{
16670					el.remove();
16671				}
16672			})
16673	}
16674
16675	addingDinamicData.prototype.pushUserBar = function(){
16676		var _this = this,
16677			$usarBarTable = $( '.article__userbar', _this.$data ),
16678			$userBar = $( '.article__userbar-loader', _this.$element );
16679		if ($('#body').data('emoji') && $userBar.length > 0 && $usarBarTable.length > 0 ){
16680			$userBar.empty().append( $usarBarTable );
16681		} else {
16682			$userBar.remove();
16683		}
16684	};
16685
16686	addingDinamicData.prototype.pushChatButtonToShare = function(){
16687		var _this = this,
16688			$shareBarChatButton = $( '.article__sharebar-chat', _this.$data),
16689			$shareBar = $( '.article__sharebar', _this.$element);
16690		if ( $shareBarChatButton.length > 0 && $shareBar.length > 0 ){
16691			$shareBar.append( $shareBarChatButton );
16692		}
16693	};
16694
16695	addingDinamicData.prototype.getClientHeigth = function(){
16696		return  Math.max( window.innerHeight || 0, ( document.getElementsByTagName( 'html' )[ 0 ] || {} ).clientHeight || 0 )
16697	};
16698
16699	$.fn.addingDinamicData = function( options ) {
16700		return this.each( function(){
16701			var instance = $.data( this, 'addingDinamicData' );
16702			if( !instance ){
16703				instance = new addingDinamicData( this, options );
16704				$.data( this, 'addingDinamicData', instance );
16705			}
16706		});
16707	};
16708
16709
16710
16711});

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.